2017-05-09 13 views
1

と仮定I Y.Forの例では同じ値で、 Xは次のようであること2つのデータフレームX & Yが、私はX内のデータを取得したい持っている:How logistical selected getするデータ

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)はXに& Y.固有のものではありません

 user_id sku_id 
8489 58104 79636 
9043 99179 113675 
9330 101391 39778 
9468 65786 73834 
…… 

私はそれがXからYにある(USER_ID、sku_id)すべてのデータを選択したいですuser_idとsku_idが要求を満たす必要があるため、isin()だけでなく同じ時期にirement。

また、私はmerge()よりも効率的な方法を探したいと思っています。

答えて

1

は、私はあなたが必要だと思うinner joinmerge中:

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 indexingisinですが、それが唯一の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() 
+0

私はそれを得るより効率的な方法を探したいと思います。 merge()は多くの時間を要します。 – Husy

+0

よろしくお願いします。ありがとうございました! – Husy

+0

@Husy - 別の解決策が速いのは確かですか?なぜなら、intカラムをstrにキャストする必要がある場合、それはより遅いからです。私のタイミングをチェックしてください。または、列を 'string'に変換する必要はありませんか? – jezrael

0

わかりませんこのソリューションがどれくらい速くなるかは分かりますが、2つのカラムをcnocatenateして、isin()を使用することができます

X['key'] = X['user_id']+"_"+X['sku_id'] 
Y['key'] = Y['user_id']+"_"+Y['sku_id'] 

ここで、XをYからフィルタリングするためにキーを使用してください。これがパフォーマンスを向上させるかどうかお知らせください。