在 pandas 数据框中,查找子集列中具有非零值的行。

12

我有一个包含4列字符串和其他整数的数据框。现在我需要找出那些至少一列是非零值(或>0)的数据行。

manwra,sahAyaH,T7,0,0,0,0,T
manwra, akriti,T5,0,0,1,0,K 
awma, prabrtih,B6, 0,1,1,0,S

我的输出应该是:
manwra, akriti,T5,0,0,1,0,K 
awma, prabrtih,B6, 0,1,1,0,S

我尝试了以下方法来获取答案。字符串的值在第0列、第1列、第2列和最后一列(-1列)中。

KT[KT.ix[:,3:-2] != 0]

我接收到的输出是:
NaN,NaNNaN,NaN,NaN,NaN,NaN,NaN
NaN,NaN,NaN,NaN,NaN,1,NaN,NaN
NaN,NaN,NaN,NaN,1,1,NaN,NaN

如何获得所需的输出结果。
4个回答

12

这里有一个替代方案,使用select_dtypes()方法:

In [41]: df[(df.select_dtypes(include=['number']) != 0).any(1)]
Out[41]:
        0          1   2  3  4  5  6  7
1  manwra     akriti  T5  0  0  1  0  K
2    awma   prabrtih  B6  0  1  1  0  S

解释:

In [42]: df.select_dtypes(include=['number']) != 0
Out[42]:
       3      4      5      6
0  False  False  False  False
1  False  False   True  False
2  False   True   True  False

In [43]: (df.select_dtypes(include=['number']) != 0).any(1)
Out[43]:
0    False
1     True
2     True
dtype: bool

这是一个更好的答案。 - piRSquared

7
假设您的数据框名称为 df
df.loc[(df.loc[:, df.dtypes != object] != 0).any(1)]

enter image description here


@piRSqaured 这个的派生能用在这个问题上吗:http://stackoverflow.com/questions/39184442/pandas-dataframe-set-all-string-values-to-nan/39184505#comment65710713_39184505 … 我用了 df.ix[:, df.dtypes == object ] ,但是无法应用到 DF 上。 - Merlin
@Merlin 简短概括一下,我认为这不太可能,至少不能直接转换。链接问题的核心是尝试将字符串转换为数值。我明确地相信数据类型是准确无误的,并且不想将它们转换。如果您将此应用于链接问题,则会忽略将字符串“2.0”转换为浮点数2.0的目的。 - piRSquared
谢谢,好的,我正在寻找 convert_objects(convert_numeric = True)的替代方法。 - Merlin
@Merlin pd.to_numeric(df.loc[:, df.dtypes == object].stack(), 'coerce').unstack() 这个怎么样? - piRSquared

2
你离正确答案很近:
 #your's    
 KT[KT.ix[:,3:-2] != 0]

 #works 
 KT[(KT.ix[:,3:6] > 0).any(1)]

        0         1   2  3  4  5  6   7
1  manwra    akriti  T5  0  0  1  0  K 
2    awma  prabrtih  B6  0  1  1  0  S

 #key diff
 (KT.ix[:,3:6] > 0)
       3      4      5      6
0  False  False  False  False
1  False  False   True  False
2  False   True   True  False

1

替代方案

一种替代方案,在某些情况下可能会很有用。例如,当绘制图形时,您不想创建新的DataFrame副本来过滤一些行并绘制它。另一个好处是,此解决方案中的列数据类型不仅限于数字,只要可以进行比较,就可以将其添加到eval调用中。

从一开始就给出指导,首先读取数据,我使用pandas.read_clipboard()函数。

c0 c1 c2 c3 c4 c5 c6 c7
manwra sahAyaH T7 0 0 0 0 T
manwra akriti T5 0 0 1 0 K 
awma prabrtih B6 0 1 1 0 S

我在这里添加了列名 c0-c7。只需选择此表并将其复制到剪贴板中,使用 Ctrl+C 即可。
import pandas as pd 
df = pd.read_clipboard()

然后通过在 DataFrame 上链接 .eval().query() 方法来实现

df.eval("all_zero = (c3==0)&(c4==0)&(c5==0)&(c6==0)").query("all_zero==False")

我们获得了期望的结果。
c0 c1 c2 c3 c4 c5 c6 c7 all_zero
1 manwra akriti T5 0 0 1 0 K False
2 awma prabrtih B6 0 1 1 0 S False

这段代码展示了一个表格,包含了多个列和行。
在 eval 调用中,我们只是对想要为零的列进行比较,如果它们都为零,则 & 符号将它们合并为 True(1),放入 all_zero 列中,然后我们可以查询结果并说我们只想要这个新列为 False 的行(我们也可以说 all_zero!=True,或者改变 eval 调用中的比较)。
如果您不想要 all_zero 列,也可以将其删除。
df.eval("all_zero = (c3==0)&(c4==0)&(c5==0)&(c6==0)").query("all_zero==False").drop('all_zero',axis=1)

c0 c1 c2 c3 c4 c5 c6 c7
1 manwra akriti T5 0 0 1 0 K
2 awma prabrtih B6 0 1 1 0 S

这是一个表格,包含多行和多列。每一行都有不同的值,其中第一列是序号,其他列分别为c0-c7。

时间/速度比较

将同一布局的更大DataFrame的解决方案速度进行比较,我们可以看到我的解决方案速度较慢(如预期),但在更广泛的过滤方面具有一些附加优点。为了比较时间,我复制了DataFrame,使其包含30,000行。

df = df.append([df]*(10000-1),ignore_index=True)

然后在其上运行不同的解决方案并计时。

Quick timing comparison for the different solutions

我会把我的解决方案留在这里以供参考!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接