如何从数据框中获取后勤选择的数据

时间:2017-05-09 05:42:32

标签: python pandas

假设我有两个数据帧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()更有效的方法。

2 个答案:

答案 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.如果这样可以提高性能,请告诉我。