【发布时间】:2021-04-14 04:12:14
【问题描述】:
我想找到col1 和col2 的值,其中第一个数据帧的col1 和col2 都在第二个数据帧中。
这些行应该在结果数据框中:
披萨,男孩
披萨,女孩
冰淇淋,男孩
因为所有三行都在第一个和第二个数据帧中。
我怎么可能做到这一点?我正在考虑使用isin,但是当我必须考虑多个列时,我不确定如何使用它。
【问题讨论】:
我想找到col1 和col2 的值,其中第一个数据帧的col1 和col2 都在第二个数据帧中。
这些行应该在结果数据框中:
披萨,男孩
披萨,女孩
冰淇淋,男孩
因为所有三行都在第一个和第二个数据帧中。
我怎么可能做到这一点?我正在考虑使用isin,但是当我必须考虑多个列时,我不确定如何使用它。
【问题讨论】:
在col1 和col2 上执行inner merge:
import pandas as pd
df1 = pd.DataFrame({'col1': ['pizza', 'hamburger', 'hamburger', 'pizza', 'ice cream'], 'col2': ['boy', 'boy', 'girl', 'girl', 'boy']}, index=range(1,6))
df2 = pd.DataFrame({'col1': ['pizza', 'pizza', 'chicken', 'cake', 'cake', 'chicken', 'ice cream'], 'col2': ['boy', 'girl', 'girl', 'boy', 'girl', 'boy', 'boy']}, index=range(10,17))
print(pd.merge(df2.reset_index(), df1, how='inner').set_index('index'))
产量
col1 col2
index
10 pizza boy
11 pizza girl
16 ice cream boy
reset_index 和set_index 调用的目的是保留df2 的索引,就像您发布的所需结果一样。如果索引不重要,那么
pd.merge(df2, df1, how='inner')
# col1 col2
# 0 pizza boy
# 1 pizza girl
# 2 ice cream boy
足够了。
或者,您可以从col1 和col2 列中构造MultiIndexs,然后调用MultiIndex.isin method:
index1 = pd.MultiIndex.from_arrays([df1[col] for col in ['col1', 'col2']])
index2 = pd.MultiIndex.from_arrays([df2[col] for col in ['col1', 'col2']])
print(df2.loc[index2.isin(index1)])
产量
col1 col2
10 pizza boy
11 pizza girl
16 ice cream boy
【讨论】:
谢谢你! 这是一个小更新。
import pandas as pd
df1 = pd.DataFrame({'col1': ['pizza', 'hamburger', 'hamburger', 'pizza', 'ice cream'], 'col2': ['boy', 'boy', 'girl', 'girl', 'boy']}, index=range(1,6))
df2 = pd.DataFrame({'col1': ['pizza', 'pizza', 'chicken', 'cake', 'cake', 'chicken', 'ice cream'], 'col2': ['boy', 'girl', 'girl', 'boy', 'girl', 'boy', 'boy']}, index=range(10,17))
df1[df1.set_index(['col1','col2']).index.isin(df2.set_index(['col1','col2']).index)]
返回:
col1 col2
1 pizza boy
4 pizza girl
5 ice cream boy
【讨论】:
如果您必须坚持使用isin 或否定版本~isin。
您可以先创建一个新列,将col1、col2 串联。然后使用isin 过滤您的数据。代码如下:
import pandas as pd
df1 = pd.DataFrame({'col1': ['pizza', 'hamburger', 'hamburger', 'pizza', 'ice cream'], 'col2': ['boy', 'boy', 'girl', 'girl', 'boy']}, index=range(1,6))
df2 = pd.DataFrame({'col1': ['pizza', 'pizza', 'chicken', 'cake', 'cake', 'chicken', 'ice cream'], 'col2': ['boy', 'girl', 'girl', 'boy', 'girl', 'boy', 'boy']}, index=range(10,17))
df1['indicator'] = df1['col1'].str.cat(df1['col2'])
df2['indicator'] = df2['col1'].str.cat(df2['col2'])
df2.loc[df2['indicator'].isin(df1['indicator'])].drop(columns=['indicator'])
给了
col1 col2
10 pizza boy
11 pizza girl
16 ice cream boy
如果您这样做,请记住确保连接两列不会产生误报,例如df1 中123 和456 的串联以及df2 中12 和3456 的串联将匹配,即使它们各自的列不匹配。您可以通过附加sep 参数来解决此问题。
df1['indicator'] = df1['col1'].str.cat(df1['col2'], sep='$$$')
df2['indicator'] = df2['col1'].str.cat(df2['col2'], sep='$$$')
【讨论】:
.drop(columns=['indicator']?
最好的方法是将字典传递给 isin()
此外,文档https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.isin.html 显示了另一个如何传递字典的示例。
【讨论】: