假设我有一个数据帧,如下所示:
Animal Color
0 Dog White
1 Cat Black
2 Dog Black
3 Dog Brown
4 Rabbit Brown
我想得到所有与这些元组匹配的索引:[('Cat', 'Black'), ('Dog', 'Brown')]
。在这种情况下,这就是[1,3]
。
我不能做df[np.isin(df['Animal'], ['Cat', 'Dog']) & np.isin(df['Color'], ['Black', 'Brown'])]
这样的事情,因为那样会给我[1,2,3]
如果这只是一列,我会使用df[np.isin(df[col], ls)]
。
如果我只关心一个元组,我本可以完成df[(df[col0] == tup[0]) & (df[col1] == tup[1])]
我只是不知道如何把这两个概念结合起来。
以下是pandas MultiIndex的一种方法。我把这个例子改成了一只红狗:
from io import StringIO
import pandas as pd
data = ''' Animal Color
0 Dog White
1 Cat Black
2 Dog Red
3 Dog Brown
4 Rabbit Brown
'''
df = pd.read_csv(StringIO(data), sep='s+', engine='python', index_col=0)
to_keep = [('Cat', 'Black'),
('Dog', 'Red'),
]
mask = pd.MultiIndex.from_frame(df[['Animal', 'Color']]).isin(to_keep)
print(df.loc[mask])
Animal Color
1 Cat Black
2 Dog Red
让我们尝试广播:
mask = (df.values[:,None,:] == np.array(a)).all(-1).any(-1)
df[mask]
输出:
Animal Color
1 Cat Black
3 Dog Brown
您只需创建一个包含逻辑的布尔序列,如下所示:
criterion = [('Cat', 'Black'), ('Dog', 'Brown')]
cond = reduce(lambda x, y: ((df['Animal'] == x[0]) & (df['Color'] == x[1])) | ((df['Animal'] == y[0]) & (df['Color'] == y[1])), criterion)
print(df[cond])
输出:
Animal Color
1 Cat Black
3 Dog Brown
您可以使用for loop
来提取索引:
df.loc[[ind
for ind, a, b in zip(df.index, df.Animal, df.Color)
if (a, b) in keep]]
Animal Color
1 Cat Black
3 Dog Brown
如果索引不重要,可以使用set index
和reset index
:
df.set_index(["Animal", "Color"], append=False, drop=False).loc[keep].reset_index(
drop=True
)
Animal Color
0 Cat Black
1 Dog Brown