所以,我有两个数据集(我的意思是数据框),如下所示 数据框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
(我们可以将其另存为人口1.csv)
数据框2:
name, age, id, acctno
abc, 11, 1001, 238238
def, 55, 2001, 299299
xxy, 90, 2020, 101010
(我们可以将其另存为人口2.csv)
因此,我们可以按以下方式读取数据
df1 = pd.read_csv('population1.csv')
df2 = pd.read_csv('population2.csv')
而且,我想得到以下结果
res = df1-df2
基于id
和acctno
的公共列。
我们可以看到,基于id
和acctno
,
dataframe2位于dataframe1中。但是dataframe1还有更多
数据框2中不常见的记录。
基于一列对两个数据帧进行子集化是straightforeword, 但是想知道如何基于两个子集来划分两个数据帧 列。
因此,结果应如下所示
ssd, 53, 1901, 238003
ggh, 52, 2221, 222222
eet, 50, 9920, 111111
答案 0 :(得分:4)
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
答案 1 :(得分:3)
使用concat
的解决方案,其中我们concat
df1
,df2
,然后再df2
,因此保证了df2
中的所有行被丢弃(如果您的DataFrame很大,这可能会降低内存效率):
pd.concat([df1, df2, df2]).drop_duplicates(['id', 'acctno'], keep=False)
name age id acctno
2 ddg 30 2920 101010
3 ssd 53 1901 238003
4 ggh 52 2221 222222
5 eet 50 9920 111111
如果您希望保留df1
中的重复项,则此答案将忽略您的意愿。
答案 2 :(得分:3)
isin
与apply
tuple
df1.loc[~df1[['id', 'acctno']].apply(tuple,1).isin(df2[['id', 'acctno']].apply(tuple,1))]
Out[215]:
name age id acctno
2 ddg 30 2920 101010
3 ssd 53 1901 238003
4 ggh 52 2221 222222
5 eet 50 9920 111111