基于行条件选择列:Pandas Python

8

I have a dataframe:

import pandas as pd
df = pd.DataFrame(np.random.randn(2, 4))
print(df)
          0         1         2         3
0  1.489198  1.329603  1.590124  1.123505
1  0.024017  0.581033  2.500397  0.156280

我想选择至少有一行值大于2的列。我尝试了下面的方法,但结果不如预期。

df[df.columns[df.iloc[(0,1)]>2]]

在这个玩具示例中,我期望的输出结果是:
       2
1.590124  
2.500397 
3个回答

9
使用 gtany 过滤 df:
In [287]:
df.ix[:,df.gt(2).any()]

Out[287]:
          2
0  1.590124
1  2.500397

在这里,我们使用 ix 选择所有行,第一个 : 和下一个参数是符合条件的列的布尔掩码:

In [288]:
df.gt(2)

Out[288]:
       0      1      2      3
0  False  False  False  False
1  False  False   True  False

In [289]:
df.gt(2).any()

Out[289]:
0    False
1    False
2     True
3    False
dtype: bool

在你的例子中,你选择了第一行和第二列的单元格值,然后尝试使用它来屏蔽列,但这只返回了第一列,因此它没有起作用:
In [291]:
df.iloc[(0,1)]

Out[291]:
1.3296030000000001

In [293]:
df.columns[df.iloc[(0,1)]>2]

Out[293]:
'0'

好的,谢谢你们两个。有人知道我的脚本应该做什么吗? - hans glick
这个 df.iloc[(0,1)] 选择了第一行第二列的单元格值并测试它是否大于2,但它不是,所以它不起作用。 - EdChum
感谢EdChum的回答。 - hans glick
EdChum,如果我想选择至少有一行低于特定值或等于特定值的列怎么办?或者如何反转一个布尔条目的数据框? - hans glick
如果您喜欢,可以使用 le<= - EdChum

3

使用用 df > 2 创建的 mask,结合 any 方法,然后通过 ix 方法选择列:

import pandas as pd
np.random.seed(18)
df = pd.DataFrame(np.random.randn(2, 4))
print(df)
          0         1         2         3
0  0.079428  2.190202 -0.134892  0.160518
1  0.442698  0.623391  1.008903  0.394249

print ((df>2).any())
0    False
1     True
2    False
3    False
dtype: bool

print (df.ix[:, (df>2).any()])
          1
0  2.190202
1  0.623391

评论编辑:

您可以逐部检查您的解决方案:

看起来它能工作,但是如果条件True,它总是选择第二列(1,Python从0开始计数)列:

print (df.iloc[(0,1)])
2.19020235741

print (df.iloc[(0,1)] > 2)
True

print (df.columns[df.iloc[(0,1)]>2])
1

print (df[df.columns[df.iloc[(0,1)]>2]])
0    2.190202
1    0.623391
Name: 1, dtype: float64

如果第一列(0 列)为 False,那么它将不会被显示,因为布尔值 TrueFalse 会强制转换为 10

np.random.seed(15)
df = pd.DataFrame(np.random.randn(2, 4))
print (df)
          0         1         2         3
0 -0.312328  0.339285 -0.155909 -0.501790
1  0.235569 -1.763605 -1.095862 -1.087766

print (df.iloc[(0,1)])
0.339284706046

print (df.iloc[(0,1)] > 2)
False

print (df.columns[df.iloc[(0,1)]>2])
0

print (df[df.columns[df.iloc[(0,1)]>2]])
0   -0.312328
1    0.235569
Name: 0, dtype: float64

如果更改列名:
np.random.seed(15)
df = pd.DataFrame(np.random.randn(2, 4))
df.columns = ['a','b','c','d']
print (df)
          a         b         c         d
0 -0.312328  0.339285 -0.155909 -0.501790
1  0.235569 -1.763605 -1.095862 -1.087766

print (df.iloc[(0,1)] > 2)
False

print (df[df.columns[df.iloc[(0,1)]>2]])
0   -0.312328
1    0.235569
Name: a, dtype: float64

好的,谢谢你们两个。有人知道我的脚本应该做什么吗? - hans glick
我尝试通过示例来解释它,请检查一下。 - jezrael

2

快速更新,因为.ix已经被弃用(自0.20.0以来)。对于最新版本的pandas,.loc将会解决问题:

df.loc[:, df.gt(2).any()]

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