我需要使用dict过滤数据框,使用键作为列名构造,值是我想要过滤的值:
filter_v = {'A':1, 'B':0, 'C':'This is right'}
# this would be the normal approach
df[(df['A'] == 1) & (df['B'] ==0)& (df['C'] == 'This is right')]
Run Code Online (Sandbox Code Playgroud)
但是我想做点什么
for column, value in filter_v.items():
df[df[column] == value]
Run Code Online (Sandbox Code Playgroud)
但这会多次过滤数据框,一次过滤一个值,而不会同时应用所有过滤器.有没有办法以编程方式进行?
编辑:一个例子:
df1 = pd.DataFrame({'A':[1,0,1,1, np.nan], 'B':[1,1,1,0,1], 'C':['right','right','wrong','right', 'right'],'D':[1,2,2,3,4]})
filter_v = {'A':1, 'B':0, 'C':'right'}
df1.loc[df1[filter_v.keys()].isin(filter_v.values()).all(axis=1), :]
Run Code Online (Sandbox Code Playgroud)
给
A B C D
0 1 1 right 1
1 0 1 right 2
3 1 0 right 3
Run Code Online (Sandbox Code Playgroud)
但预期的结果是
A B C D
3 1 0 right 3
Run Code Online (Sandbox Code Playgroud)
只应选择最后一个.
DSM*_*DSM 38
IIUC,您应该能够做到这样的事情:
>>> df1.loc[(df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)]
A B C D
3 1 0 right 3
Run Code Online (Sandbox Code Playgroud)
这可以通过制作一个系列进行比较:
>>> pd.Series(filter_v)
A 1
B 0
C right
dtype: object
Run Code Online (Sandbox Code Playgroud)
选择相应的部分df1:
>>> df1[list(filter_v)]
A C B
0 1 right 1
1 0 right 1
2 1 wrong 1
3 1 right 0
4 NaN right 1
Run Code Online (Sandbox Code Playgroud)
找到匹配的位置:
>>> df1[list(filter_v)] == pd.Series(filter_v)
A B C
0 True False True
1 False False True
2 True False False
3 True True True
4 False False True
Run Code Online (Sandbox Code Playgroud)
发现他们所有的比赛:
>>> (df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)
0 False
1 False
2 False
3 True
4 False
dtype: bool
Run Code Online (Sandbox Code Playgroud)
最后使用它来索引到df1:
>>> df1.loc[(df1[list(filter_v)] == pd.Series(filter_v)).all(axis=1)]
A B C D
3 1 0 right 3
Run Code Online (Sandbox Code Playgroud)
对于传递过滤器值数组而不是单个值的情况的上述抽象(类似于 pandas.core.series.Series.isin())。使用相同的示例:
df1 = pd.DataFrame({'A':[1,0,1,1, np.nan], 'B':[1,1,1,0,1], 'C':['right','right','wrong','right', 'right'],'D':[1,2,2,3,4]})
filter_v = {'A':[1], 'B':[1,0], 'C':['right']}
##Start with array of all True
ind = [True] * len(df1)
##Loop through filters, updating index
for col, vals in filter_v.items():
ind = ind & (df1[col].isin(vals))
##Return filtered dataframe
df1[ind]
##Returns
A B C D
0 1.0 1 right 1
3 1.0 0 right 3
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10203 次 |
| 最近记录: |