我有一个包含product_id和它们的property _id的巨大数据,请注意,对于每个属性,都以新索引开头。我需要为每个property_id同时通过不同的product_id值进行过滤。有办法快点吗?
out_df
product_id property_id
0 3588 1
1 3588 2
2 3588 5
3 3589 1
4 3589 3
5 3589 5
6 3590 1
7 3590 2
8 3590 5例如,希望通过两个属性对每个product_id进行过滤,这些属性在不同的行(如out_df.loc[(out_df['property_id'] == 1) & (out_df['property_id'] == 2)] )分配,而不是)。我需要这样的东西,但是对每个product_id列的所有行都同时工作。
我知道这可以通过groupby变成列表
3587 [2, 1, 5]
3588 [1, 3, 5]
3590 [1, 2, 5]并在列表中找到交叉口。
gp_df.apply(lambda r: {1, 2} < (set(r['property_id'])), axis=1) 但这需要时间,同时Pandas的通用过滤也大大优化了速度(请相信在搜索引擎ElasticSearch、狮身人面像等中使用一些复杂的正、逆索引)。
预期输出:其中{1和2}都有。
3587 [2, 1, 5]
3590 [1, 2, 5]发布于 2018-06-27 12:28:09
由于这既是一个功能问题,也是一个性能问题,所以我将使用这样的交叉方法:
df = pd.DataFrame({'product_id': [3588, 3588, 3588, 3589, 3589, 3589, 3590, 3590,3590],
'property_id': [1, 2, 5, 1, 3, 5, 1, 2, 5]})
df = df.set_index(['property_id'])
print("The full DataFrame:")
print(df)
start = time()
for i in range(1000):
s1 = df.loc[(1), 'product_id']
s2 = df.loc[(2), 'product_id']
s_done = pd.Series(list(set(s1).intersection(set(s2))))
print("Overlapping product_id's")
print(time()-start)迭代查找1000次需要0.93秒在我的ThinkPad T450s上。我冒昧地测试了@jezrael的两个建议,它们是在2.11和2.00秒时提出的,groupby的方法是,软件工程方面的建议更优雅。
根据数据集的大小和性能的重要性,您还可以切换到更简单的数据类型,如经典字典,并获得进一步的速度。
木星笔记本可以在这里找到:intersection.ipynb
发布于 2018-06-27 11:46:41
你是说像这样的事吗?
result = out_df.loc[out_df['property_id'].isin([1,2]), :]如果你想要的话,你可以根据product_id放一个副本.
发布于 2018-06-27 11:48:27
最简单的方法是在比较集中使用GroupBy.transform:
s = {1, 2}
a = df[df.groupby('product_id')['property_id'].transform(lambda r: s < set(r))]
print (a)
product_id property_id
0 3588 1
1 3588 2
2 3588 5
6 3590 1
7 3590 2
8 3590 5另一种解决方案是只筛选集合的值,首先删除重复的值:
df1 = df[df['property_id'].isin(s) & ~df.duplicated(['product_id', 'property_id'])]然后,有必要检查每个组的长度是否与这个解决方案的集合长度相同。
f, u = df1['product_id'].factorize()
ids = df1.loc[np.bincount(f)[f] == len(s), 'product_id'].unique()最后,使用product_id按条件过滤所有行:
a = df[df['product_id'].isin(ids)]
print (a)
product_id property_id
0 3588 1
1 3588 2
2 3588 5
6 3590 1
7 3590 2
8 3590 5https://stackoverflow.com/questions/51061711
复制相似问题