假设我有两个数据帧X&是的,我想在X中获得Y中具有相同值的数据。例如, X是这样的:
user_id sku_id time model_id type cate brand
0 27630 37957 2016-02-01 07:43:14 NaN 6 8 489
1 65377 165713 2016-02-01 11:09:34 NaN 6 5 124
2 10396 65823 2016-02-01 08:20:59 NaN 6 6 78
……
和Y是这样的:
user_id sku_id
8489 58104 79636
9043 99179 113675
9330 101391 39778
9468 65786 73834
……
(user_id,sku_id)在X& Y中不是唯一的。我想从X中选择(user_id,sku_id)在Y中的所有数据。它不仅仅是isin(),因为user_id和sku_id应该同时满足要求。
我也希望找到一种比merge()更有效的方法。
答案 0 :(得分:1)
我认为您需要merge
中的inner join
:
df = pd.merge(X, Y)
或者:
X.set_index(['user_id', 'sku_id'], inplace=True)
df = Y.join(X, how='inner', on=['user_id', 'sku_id'])
另一个解决方案是isin
boolean indexing
,但只有在user_id
唯一的情况下才有效:
X = X.set_index('user_id')
df = X[X['sku_id'].isin(Y.set_index('user_id')['sku_id'])].reset_index()
通常,最好也是最快的是在pandas中使用merge
:
In [143]: %%timeit
...: (Y1.join(X1.set_index(['user_id', 'sku_id']),how='inner',on=['user_id','sku_id']))
...:
1 loop, best of 3: 583 ms per loop
In [144]: %%timeit
...: (pd.merge(X2,Y2))
...:
1 loop, best of 3: 487 ms per loop
In [145]: %%timeit
...: x = pd.MultiIndex.from_arrays([X['user_id'], X['sku_id']])
...: y = pd.MultiIndex.from_arrays([Y['user_id'], Y['sku_id']])
...: inter = x.intersection(y)
...: a = X.set_index(['user_id', 'sku_id']).loc[inter].reset_index()
...:
1 loop, best of 3: 1.26 s per loop
#another solution
In [146]: %%timeit
...: X[(X['user_id'].astype(str) +"_" +X['sku_id'].astype(str)).isin((Y['user_id'].astype(str)+"_"+Y['sku_id'].astype(str)))]
...:
1 loop, best of 3: 6.34 s per loop
如果所有值都是字符串(X = X.astype(str)
,Y = Y.astype(str)
):
In [147]: %%timeit
...: X[(X['user_id'] +"_" +X['sku_id']).isin((Y['user_id']+"_"+Y['sku_id']))]
...:
1 loop, best of 3: 953 ms per loop
时间安排的代码:
np.random.seed(123)
N = 1000000
X = pd.DataFrame({'user_id':np.random.randint(10000, size=N),
'sku_id': np.random.randint(10000, size=N),
'brand': np.random.randint(10000, size=N)})
X = X.drop_duplicates(subset=['user_id', 'sku_id'])
print (X)
X1,X2 = X.copy(), X.copy()
Y = pd.DataFrame({'user_id':np.random.randint(10000, size=N),
'sku_id': np.random.randint(10000, size=N)})
print (Y)
Y = Y.drop_duplicates(subset=['user_id', 'sku_id'])
Y1,Y2 = Y.copy(), Y.copy()
答案 1 :(得分:0)
不确定此解决方案的速度有多快,但您可以尝试cnocatenate这两列,然后使用isin()
X['key'] = X['user_id']+"_"+X['sku_id']
Y['key'] = Y['user_id']+"_"+Y['sku_id']
现在只需使用密钥从Y过滤X.如果这样可以提高性能,请告诉我。