Python 带Dict生成器的Pandas多列布尔索引/选择

Python 带Dict生成器的Pandas多列布尔索引/选择,python,pandas,Python,Pandas,假设您有一个包含大量列的数据帧df,比如50列,而df没有任何索引(即index_col=None)。您希望选择由必需的列列表定义的列的子集,但只希望返回满足由各种布尔索引定义的多个条件的行。有没有办法使用dict生成器一致地生成选择语句 例如: df = pd.DataFrame(np.random.randn(100,50),index=None,columns=["Col" + ("%03d" % (i + 1)) for i in range(50)]) # df.columns =

假设您有一个包含大量列的数据帧df,比如50列,而df没有任何索引(即index_col=None)。您希望选择由必需的列列表定义的列的子集,但只希望返回满足由各种布尔索引定义的多个条件的行。有没有办法使用dict生成器一致地生成选择语句

例如:

df = pd.DataFrame(np.random.randn(100,50),index=None,columns=["Col" + ("%03d" % (i + 1)) for i in range(50)])

# df.columns = Index[u'Col001', u'Col002', ..., u'Col050']

required_columns_list = ['Col002', 'Col012', 'Col025', 'Col032', 'Col033']
现在让我们想象一下,我定义:

boolean_index_dict = {'Col001':"MyAccount", 'Col002':"Summary", 'Col005':"Total"}
我想使用dict生成器来构造多个布尔索引:

df.loc[GENERATOR_USING_boolean_index_dict, required_columns_list].values
上述生成器布尔方法等效于:

df.loc[(df['Col001']=="MyAccount") & (df['Col002']=="Summary") & (df['Col005']=="Total"), ['Col002', 'Col012', 'Col025', 'Col032', 'Col033']].values
希望您能看到,这在操作大型数据帧时非常有用的“模板”,然后可以在布尔索引中定义布尔索引。如果您能让我知道在熊猫中这是否可行,以及如何使用布尔索引构建生成器,我将不胜感激? 非常感谢和亲切的问候, 伯蒂


p、 如果你想测试一下,你需要用文本填充一些df列。如果测试需要,使用随机数的df定义只是一个起点…

假设这是您的df:

df = pd.DataFrame(np.random.randint(0,4,(100,50)),index=None,columns=["Col" + ("%03d" % (i + 1)) for i in range(50)])

# the first five cols and rows:
df.iloc[:5,:5]

   Col001  Col002  Col003  Col004  Col005
0       2       0       2       3       1
1       0       1       0       1       3
2       0       1       1       0       3
3       3       1       0       2       1
4       1       2       3       1       0
与您的示例相比,所有列都用0、1、2或3的整数填充

让我们定义标准:

req = ['Col002', 'Col012', 'Col025', 'Col032', 'Col033']
filt = {'Col001': 2, 'Col002': 2, 'Col005': 2}
所以我们需要一些列,其中一些其他列都包含值2

然后,您可以通过以下方式获得结果:

df.loc[df[filt.keys()].apply(lambda x: x.tolist() == filt.values(), axis=1), req]
就我而言,结果如下:

    Col002  Col012  Col025  Col032  Col033
43       2       2       1       3       3
98       2       1       1       1       2
让我们检查这些行所需的列:

df[filt.keys()].iloc[[43,98]]

    Col005  Col001  Col002
43       2       2       2
98       2       2       2
和其他一些(不匹配)行:


我开始越来越喜欢熊猫了。

根据您描述的输入,您能准确地说明这里的预期输出是什么吗?对于抽象问题,输入和输出的清晰示例非常有用。请参阅0.13中的一个新功能(很快就会出现)。这允许您直接执行这种类型的查询。谢谢Jeff,如果我理解正确,df.isin()可能是使用包含列子集和列值的dict的方法?同样对于Pawelmhm,Rutger Kassies演示了如何使用df.apply方法作为多重布尔索引来完成此任务。非常感谢。嗨,拉格,谢谢你的回答,这正是我想要的。我还是不明白你的发电机是怎么工作的。我所能理解的是df[filt.keys()]返回一个包含布尔索引中使用的列的数据帧子集。然后Pandas.apply方法将函数应用于行,但是为什么我们需要匿名函数中的x.tolist()?干得好,没有你的帮助我是不可能到达那里的。你对第一部分和第二部分都是正确的;由于
filt.values()
返回一个列表,因此在lambda函数中将该行转换为一个列表可以直接比较是否相等,因此
x.tolist()
将该行转换为一个列表,而不是默认序列。值得注意的是,Pandas将子集中的列重新排序为“filt.keys()”,这保证了
x.tolist()
中的值顺序与
filt.values()中的值顺序相同
df[filt.keys()].iloc[[44,99]]

    Col005  Col001  Col002
44       3       0       3
99       1       0       0