使用布尔值选择 Pandas 数据框列

43

我想使用一个布尔值来选择包含超过4000个条目的数据框comb中的列,该数据框有超过1,000列。这个表达式会给我一个布尔值(True/False)的结果:

criteria = comb.ix[:,'c_0327':].count()>4000
我想使用它仅选择新数据框中的 True 列。
下面的代码只会报错 "Unalignable boolean Series key provided":
comb.loc[criteria,]

我也尝试了:

comb.ix[:, comb.ix[:,'c_0327':].count()>4000] 

与此问题的答案类似dataframe boolean selection along columns instead of row,但这给了我相同的错误:"Unalignable boolean Series key provided"

comb.ix[:,'c_0327':].count()>4000
产生:
c_0327    False
c_0328    False
c_0329    False
c_0330    False
c_0331    False
c_0332    False
c_0333    False
c_0334    False
c_0335    False
c_0336    False
c_0337     True
c_0338    False
.....

你不想要 comb[criteria.columns] 吗? - EdChum
1
comb[criteria.columns]会出现“'Series' object has no attribute 'columns'”的错误提示。 - dartdog
7个回答

45

返回的是一个Series对象,其中列名为索引,布尔值为行值。

我认为您实际上想要的是:

现在应该可以运行此代码:

comb[criteria.index[criteria]]
基本上,它使用来自条件的索引值和布尔值来进行掩码处理,这将返回一个列名数组,我们可以使用它从原始数据框中选择感兴趣的列。

3
看到这里,我感到惊讶,居然没有更简单的方法来完成这件事情。 - Areza
2
这个回答已经过时,而且是5年前的。请查看下面我的回答,以获取更为直接的方法。 - johnDanger
@johnDanger 回答不错,但我不确定我同意从“m[f] 用于行过滤”到“m.loc[:,f] 用于列过滤”是很直观的。 - c z
1
@johnDanger的回答中的“直截了当”之处在于您只需要一次使用criteria,因此您不需要单独定义变量(而是可以直接在m.loc [:,expression_of_criteria_itself]中使用表达式本身)。 - chickenNinja123

33
在 pandas 0.25 中:
comb.loc[:, criteria]

返回一个由布尔列表或序列选择的DataFrame。

对于多个条件:

comb.loc[:, criteria1 & criteria2]

对于使用索引条件选择行:

comb[criteria]

注意: 按位运算符&是必需的(而不是and)。请参见Pandas中用于布尔索引的逻辑运算符

其他注意事项: 如果标准是表达式(例如comb.columnX > 3),并且使用了多个标准,请记得将每个表达式括在括号内!这是因为&, |>, ==, ect.具有更高的优先级(而and, or则优先级较低)。


7

您也可以使用以下方法:

# 按列过滤(假设条件长度等于comb的列数)
comb.ix[:, criteria]
comb.iloc[:, criteria.values]
# 按行过滤(假设条件长度等于comb的行数) comb[criteria]

2
第一个答案看起来在选择掩码列方面最为优雅。唯一的技巧是需要执行 comb.iloc[:, criteria.values],因为系列不是这种类型的 iloc 切片的有效参数。 - Mischa Lisovyi
我应该明确指出我期望的标准是一个布尔列表。很好发现。 - Yohan Obadia

3
你可以传递一个布尔数组到 loc 方法中,以指示应该保留哪些列和不保留哪些列。

例如,
>>> df
    A   B   C   D    E
0  73  15  55  33  foo
1  63  64  11  11  bar
2  56  72  57  55  foo

>>> df.loc[:, [True, True, False, False, True]]
    A   B    E
0  73  15  foo
1  63  64  bar
2  56  72  foo

1

7
只是为了明确,这将返回一个 numpy.ndarray,而不是一个 pandas.DataFrame - Keith Hughitt

-1
另一种解决方案是将comb转置,使其列作为索引,然后在结果子集上进行转置:
comb.T[criteria].T

虽然不是特别优雅,但至少比主要解决方案更短/不那么重复。


1
已经有提出的解决方案比被接受的解决方案更短/不那么重复,但也更加优雅。 - Jean Paul
1
支持@JeanPaul的观点...最好避免转置。 - william_grisaitis
@william_grisaitis 转置有什么问题吗?它们是内存/计算密集型的,还是你只是觉得 T 不美观,或者其他什么原因? - Seth Johnson
1
@SethJohnson它们可能会非常慢。虽然不是专家,但这是我的经验。如果我要猜的话,它正在为所有内容重新分配内存(而不是零拷贝操作)。 - william_grisaitis

-1
另一种方法是使用Python内置的filter函数:
def satisfies_criteria(column):
    return comb[column].count() > 4000


cols = filter(satisfies_criteria, df.columns)
df[cols]

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