如何选择与多列中的值匹配的行?
例如,我们有以下df
k1 | k2 | v1 | v2
1 | 2 | 3 | 4
1 | 5 | 5 | 6
1 | 8 | 8 | 9
我正在尝试选择中间行:
key_names = ["k1", "k2"]
keys = [1, 5]
selected_rows = df.loc[df[key_names].isin(keys)]
我收到以下错误:
ValueError: Cannot index with multidimensional key
预期输出为:
1 | 5 | 5 | 6
谢谢
答案 0 :(得分:4)
TLDR
根据您的要求使用以下之一:
df[(df[key_names] == keys).all(1)]
df[df[key_names].isin(keys).all(1)]
您已经很接近了,您已经成功创建了蒙版,只需要将其缩小为一个尺寸以进行索引。
>>> df[key_names].isin(keys)
k1 k2
0 True False
1 True True
2 True False
您只对所有值均为True
的行感兴趣,因此可以使用all
减小第一轴的尺寸。
>>> df[key_names].isin(keys).all(1)
0 False
1 True
2 False
dtype: bool
这里需要说明的一点是,isin
与顺序无关,因此,使用另一种顺序的值可以获得相同的结果。
>>> df[key_names].isin([5, 1]).all(1)
0 False
1 True
2 False
dtype: bool
如果您只需要精确的排序匹配,请使用==
进行广播比较,而不要使用isin
>>> (df[key_names] == keys).all(1)
0 False
1 True
2 False
dtype: bool
>>> (df[key_names] == [5, 1]).all(1)
0 False
1 False
2 False
dtype: bool
这里的最后一步是使用您创建的1D
掩码为原始DataFrame编制索引:
>>> df[(df[key_names] == keys).all(1)]
k1 k2 v1 v2
1 1 5 5 6
答案 1 :(得分:0)
也许 df.query('k1 == 1和k2 == 5')就足够了吗?
或df[df.apply(lambda row: {1,5} == set((row.k1, row.k2)), axis=1)]
第二种解决方案可以按任何按键顺序使用。