簡體   English   中英

如果列總和等於單個列,則刪除行

[英]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

也許最好的方法是結合EdChumMaxU解決方案:

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.

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