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