[英]Dropping a row if sum of columns equals an individual column
我有一個看起來像這樣的數據框:
Id Var1_Belgium var1_France var1_Germany
x 1 2 0
y 1 0 0
z 0 2 0
u 1 3 2
v 1 0 4
我想要的是刪除僅在一個國家/地區觀察信息的任何行。 因此,如果所有國家/地區中的值(除了一個等於零)都等於零,我想省略該行。 數據框中有幾十個國家。
考慮此問題的另一種方法是,如果所有var1的總和等於var1的單個列,則應刪除該行。 不知道這是否使它更容易。
這是應該發生的情況:
Id Var1_Belgium var1_France var1_Germany
x 1 2 0
u 1 3 2
v 1 0 4
因此,應該刪除只有一個國家/地區具有非零值的任何行。
注意:列和變量比上面的多。
我正在嘗試使用具有數百萬個觀測值的df做到這一點,最好是一種有效的方法。
您可以使用filter()
僅選擇類似var1_
列,然后使用(r != 0).sum()
條件-它將得出0
(假)和1
(真)的總和。 因此,如果總和大於1
則表示有多個國家/地區的值非零:
In [52]: df
Out[52]:
Id var1_Belgium var1_France var1_Germany
0 1 0 0 122
1 2 0 100 120
2 3 100 0 0
3 4 5 6 7
4 5 11 12 13
In [55]: df.filter(like='var1_').apply(lambda r: (r != 0), axis=1)
Out[55]:
var1_Belgium var1_France var1_Germany
0 False False True
1 False True True
2 True False False
3 True True True
4 True True True
In [53]: df.filter(like='var1_').apply(lambda r: (r != 0).sum() > 1, axis=1)
Out[53]:
0 False
1 True
2 False
3 True
4 True
dtype: bool
結果
In [54]: df[df.filter(like='var1_').apply(lambda r: (r != 0).sum() > 1, axis=1)]
Out[54]:
Id var1_Belgium var1_France var1_Germany
1 2 0 100 120
3 4 5 6 7
4 5 11 12 13
IIUC然后我認為這應該起作用:
In [314]:
df[(df.ix[:,'Var1_Belgium':] == 0).sum(axis=1) < len(df.ix[:,'Var1_Belgium':].columns) - 1]
Out[314]:
Id Var1_Belgium var1_France var1_Germany
0 x 1 2 0
3 u 1 3 2
4 v 1 0 4
因此,這只會將國家/地區列與0
進行比較並將它們sum
然后與列數-1進行比較,並屏蔽符合條件/
或更簡單:
In [315]:
df[(df.ix[:,'Var1_Belgium':] != 0).sum(axis=1) > 1]
Out[315]:
Id Var1_Belgium var1_France var1_Germany
0 x 1 2 0
3 u 1 3 2
4 v 1 0 4
也許最簡單的方法是使用iloc
選擇所有列而無需先進行:
print df[(df.iloc[:,1:] != 0).sum(axis=1) > 1]
Id Var1_Belgium var1_France var1_Germany
0 x 1 2 0
3 u 1 3 2
4 v 1 0 4
print df[(df.filter(like='var1') != 0).sum(1) > 1]
Id var1_Belgium var1_France var1_Germany
0 x 1 2 0
3 u 1 3 2
4 v 1 0 4
時間 :
df = pd.concat([df]*1000).reset_index(drop=True)
In [787]: %timeit df[df.filter(like='var1_').apply(lambda r: (r != 0).sum() > 1, axis=1)]
1 loops, best of 3: 746 ms per loop
In [788]: %timeit df[(df.ix[:,'Var1_Belgium':] != 0).sum(axis=1) > 1]
The slowest run took 4.49 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 1.39 ms per loop
In [789]: %timeit df[(df.filter(like='var1') != 0).sum(1) > 1]
The slowest run took 4.64 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 1.48 ms per loop
In [790]: %timeit df[(df.iloc[:,1:] != 0).sum(axis=1) > 1]
1000 loops, best of 3: 1.34 ms per loop
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.