は、私はあなたが必要だと思うinner join
merge
中:
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'])
別の解決策は、boolean indexing
とisin
ですが、それが唯一のuser_id
ユニークな場合に機能します。
X = X.set_index('user_id')
df = X[X['sku_id'].isin(Y.set_index('user_id')['sku_id'])].reset_index()
一般的に、
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)
)している場合::パンダでmerge
を使用しているの最善かつ迅速なタイミングため
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()
私はそれを得るより効率的な方法を探したいと思います。 merge()は多くの時間を要します。 – Husy
よろしくお願いします。ありがとうございました! – Husy
@Husy - 別の解決策が速いのは確かですか?なぜなら、intカラムをstrにキャストする必要がある場合、それはより遅いからです。私のタイミングをチェックしてください。または、列を 'string'に変換する必要はありませんか? – jezrael