簡體   English   中英

在算術運算中將NaN視為零?

[英]Treating NaN as zero in arithmetic operations?

這是我正在努力解決的一個簡單例子:

In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: test = pd.DataFrame(np.random.randn(4,4),columns=list('ABCD'))
In [4]: for i in range(4):
  ....:    test.iloc[i,i] = np.nan

In [5]: test
Out[5]:
           A         B         C         D
0        NaN  0.136841 -0.854138 -1.890888
1  -1.261724       NaN  0.875647  1.312823
2   1.130999 -0.208402       NaN  0.256644
3  -0.158458 -0.305250  0.902756       NaN 

現在,如果我使用sum對行求和,則所有NaN值都被視為零:

In [6]: test['Sum'] = test.loc[:,'A':'D'].sum(axis=1)

In [7]: test
Out[7]: 
          A         B         C         D       Sum
0       NaN  0.136841 -0.854138 -1.890888 -2.608185
1 -1.261724       NaN  0.875647  1.312823  0.926745
2  1.130999 -0.208402       NaN  0.256644  1.179241
3 -0.158458 -0.305250  0.902756       NaN  0.439048    

但就我而言,我可能需要先對價值觀做一些工作; 例如縮放它們:

In [8]: test['Sum2'] = test.A + test.B/2 - test.C/3 + test.D

In [9]: test
Out[9]: 
          A         B         C         D       Sum  Sum2
0       NaN  0.136841 -0.854138 -1.890888 -2.608185   NaN
1 -1.261724       NaN  0.875647  1.312823  0.926745   NaN
2  1.130999 -0.208402       NaN  0.256644  1.179241   NaN
3 -0.158458 -0.305250  0.902756       NaN  0.439048   NaN

如您所見, NaN值會進入算術運算以產生NaN輸出,這正是您所期望的。

現在,我不想用零替換我的數據幀中的所有NaN值:我有助於區分零和NaN 我可以用其他東西代替NaN :我正在處理大量的學生成績,我需要區分零等級和NaN ,我現在用它來表示特定的評估任務不是嘗試。 (它取代了傳統電子表格中的空白單元格。)但無論我用什么替換NaN值,它都需要在我可能執行的操作中被視為零。 我有什么選擇?

使用fillna功能

test['Sum2'] = test.A.fillna(0) + test.B.fillna(0)/2 - test.C.fillna(0)/3 + test.D.fillna(0)

如果數據幀不是很大,您可以嘗試:

test["Sum"] = test.sum(axis=1)
test2 = test.fillna(0)
test["Sum2"] = test2.A + test2.B/2 - test2.C/3 + test2.D
del test2

知道是否有辦法只在一行中進行第二次求和將會很有趣。

更新

如果你有1e5行或更少,我建議的方法比kmcodes建議的方法略快,那么事情會發生變化。

n = int(1e5)
test = pd.DataFrame(np.random.randn(n,4),columns=list('ABCD'))
for i in range(4):
    test.iloc[i,i] = np.nan

%%timeit
test2 = test.fillna(0)
test["Sum2"] = test2.A + test2.B/2 - test2.C/3 + test2.D
del test2
3.95 ms ± 51.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
test['Sum2'] = test.A.fillna(0) + test.B.fillna(0)/2 - test.C.fillna(0)/3 + test.D.fillna(0)
4.12 ms ± 16.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

更新2

我找到了這個

在你的情況下,你可以

weights = [1, 1/2, -1/3, 1]
test["Sum2"] = test.fillna(0).mul(weights).sum(axis=1)

請記住,這似乎始終比其他兩個慢。

您還可以連接並找到總和以獲得sum()提供的功能

test['Sum2'] = pd.concat([test.A,test.B/2, test.C/(-3),test.D],1).sum(1)

       A         B         C         D      Sum2
0       NaN  0.181923 -0.526074  1.084549  1.350869
1  0.999836       NaN -0.862583 -0.473933  0.813431
2  1.043463  0.252743       NaN -0.863199  0.306635
3 -0.047286  1.432500  0.100041       NaN  0.635616

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM