首页 > 解决方案 > pandas基于多列子集两个数据帧

问题描述

所以,我有两个数据集(我的意思是数据框)如下数据框1:

name, age, id, acctno
abc, 23, 1001, 238238
dhd, 22, 2001, 299299
ddg, 30, 2920, 101010
ssd, 53, 1901, 238003
ggh, 52, 2221, 222222
eet, 50, 9920, 111111

(我们可以将其保存为 population1.csv)

数据框2:

name, age, id, acctno
abc, 11, 1001, 238238
def, 55, 2001, 299299
xxy, 90, 2020, 101010

(我们可以将其保存为 population2.csv)

所以,我们可以读取数据如下

df1 = pd.read_csv('population1.csv')
df2 = pd.read_csv('population2.csv')

而且,我想得到以下结果

res = df1-df2

基于 和 的公共idacctno。我们可以看到,基于idand acctno,dataframe2 在 dataframe1 中。但是dataframe1还有一些在dataframe2中不常见的记录。

基于一列对两个数据帧进行子集化是直接的前言,但是想知道如何基于两列对两个数据帧进行子集化。

所以,结果应该如下

ssd, 53, 1901, 238003
ggh, 52, 2221, 222222
eet, 50, 9920, 111111

标签: pythonpandasdataframesubset

解决方案


设置

def rpd(text='', sep='\s{1,}', *args, **kwargs):
  kw = dict(engine='python', sep=sep)
  return pd.read_csv(pd.io.common.StringIO(text), *args, **kw, **kwargs)

df1 = rpd(sep=',\s*', text="""\
name, age, id, acctno
abc, 23, 1001, 238238
dhd, 22, 2001, 299299
ddg, 30, 2920, 101010
ssd, 53, 1901, 238003
ggh, 52, 2221, 222222
eet, 50, 9920, 111111""")

df2 = rpd(sep=',\s*', text="""\
name, age, id, acctno
abc, 11, 1001, 238238
def, 55, 2001, 299299
xxy, 90, 2020, 101010""")

mask

df2_tups = [*zip(df2.id, df2.acctno)]
mask = [t not in df2_tups for t in zip(df1.id, df1.acctno)]
df1[mask]

  name  age    id  acctno
2  ddg   30  2920  101010
3  ssd   53  1901  238003
4  ggh   52  2221  222222
5  eet   50  9920  111111

merge

merge函数/方法有一个indicator参数,如果设置为True添加一个列,该列告诉您合并标识符在哪个数据源中。在您的情况下,您只想获取剩下的那些。

df1.merge(
    df2[['id', 'acctno']], how='left', indicator=True
).query('_merge == "left_only"').drop('_merge', 1)

  name  age    id  acctno
2  ddg   30  2920  101010
3  ssd   53  1901  238003
4  ggh   52  2221  222222
5  eet   50  9920  111111

谷歌 Colab

GitHub


推荐阅读