从满足(字典?)要求的 PANDAS 数据框中获取行
Getting rows from a PANDAS dataframe that fulfill (a dictionary?) of requirements
我想通过指定 变量 组 column==value
条件来过滤 pandas DataFrame
的行。
假设我们有这样一个玩具 DataFrame
:
from itertools import product
from numpy.random import rand
df = pd.DataFrame([[i,j,k,rand()] for i,j,k,m in product(range(2), repeat=3)],
columns=['par1','par2','par3','val'])
有些行看起来像:
par1 par2 par3 val
0 0 0 0 0.464625
1 0 0 1 0.481147
2 0 1 0 0.817992
3 0 1 1 0.639930
4 1 0 0 0.035160
5 1 0 1 0.549517
6 1 1 0 0.172746
7 1 1 1 0.855064
我想知道 select 某些行的最佳方式是指定一些行
column==value
条件不需要包括所有列,也不需要总是相同的列甚至相同数量的列。我认为 dict
是指定条件的一种相当自然的方式:
conditions = {'par1':1, 'par3':0}
在这种情况下,df.par2
的任何值都可以。
df.isin()
我知道 df.isin()
带有 dict
个参数以及 all(1)
as shown in the docs(本节的最后一个代码块)。问题是未通过 df.isin()
调用中的条件的列中的值给出 False
,因此对 all(1)
的后续调用给出了一个空的 DataFrame。 (一个解决办法是添加所有缺失的列,并将所有可能的值作为标准,但这听起来不是一个好的解决方案)
df.query()
在写这个问题时,我想到了另一个尝试。这个看起来好多了:根据条件 dict
.
自动构建查询
df.query(' & '.join(['({} == {})'.format(k,v)
for k,v in conditions.iteritems()]))
它按预期工作...
par1 par2 par3 val
4 1 0 0 0.035160
6 1 1 0 0.172746
仍然,我不完全相信,我想知道是否有更多的 natural/proper/clear 方法来做到这一点... Pandas 是如此之大,我总是有我想念的印象正确的做事方式...:P
您可以制作一系列 conditions
和 select 只有那些列:
>>> df[(df[list(conditions)] == pd.Series(conditions)).all(axis=1)]
par1 par2 par3 val
4 1 0 0 0.937192
6 1 1 0 0.536029
这是可行的,因为在我们制作系列后,它会将我们需要的方式与以下方式进行比较:
>>> df[list(conditions)]
par1 par3
0 0 0
1 0 1
2 0 0
3 0 1
4 1 0
5 1 1
6 1 0
7 1 1
>>> df[list(conditions)] == pd.Series(conditions)
par1 par3
0 False True
1 False False
2 False True
3 False False
4 True True
5 True False
6 True True
7 True False
我想通过指定 变量 组 column==value
条件来过滤 pandas DataFrame
的行。
假设我们有这样一个玩具 DataFrame
:
from itertools import product
from numpy.random import rand
df = pd.DataFrame([[i,j,k,rand()] for i,j,k,m in product(range(2), repeat=3)],
columns=['par1','par2','par3','val'])
有些行看起来像:
par1 par2 par3 val
0 0 0 0 0.464625
1 0 0 1 0.481147
2 0 1 0 0.817992
3 0 1 1 0.639930
4 1 0 0 0.035160
5 1 0 1 0.549517
6 1 1 0 0.172746
7 1 1 1 0.855064
我想知道 select 某些行的最佳方式是指定一些行
column==value
条件不需要包括所有列,也不需要总是相同的列甚至相同数量的列。我认为 dict
是指定条件的一种相当自然的方式:
conditions = {'par1':1, 'par3':0}
在这种情况下,df.par2
的任何值都可以。
df.isin()
我知道 df.isin()
带有 dict
个参数以及 all(1)
as shown in the docs(本节的最后一个代码块)。问题是未通过 df.isin()
调用中的条件的列中的值给出 False
,因此对 all(1)
的后续调用给出了一个空的 DataFrame。 (一个解决办法是添加所有缺失的列,并将所有可能的值作为标准,但这听起来不是一个好的解决方案)
df.query()
在写这个问题时,我想到了另一个尝试。这个看起来好多了:根据条件 dict
.
df.query(' & '.join(['({} == {})'.format(k,v)
for k,v in conditions.iteritems()]))
它按预期工作...
par1 par2 par3 val
4 1 0 0 0.035160
6 1 1 0 0.172746
仍然,我不完全相信,我想知道是否有更多的 natural/proper/clear 方法来做到这一点... Pandas 是如此之大,我总是有我想念的印象正确的做事方式...:P
您可以制作一系列 conditions
和 select 只有那些列:
>>> df[(df[list(conditions)] == pd.Series(conditions)).all(axis=1)]
par1 par2 par3 val
4 1 0 0 0.937192
6 1 1 0 0.536029
这是可行的,因为在我们制作系列后,它会将我们需要的方式与以下方式进行比较:
>>> df[list(conditions)]
par1 par3
0 0 0
1 0 1
2 0 0
3 0 1
4 1 0
5 1 1
6 1 0
7 1 1
>>> df[list(conditions)] == pd.Series(conditions)
par1 par3
0 False True
1 False False
2 False True
3 False False
4 True True
5 True False
6 True True
7 True False