我知道这个话题已经解决了上千次。但是我找不到解决办法。
我正在尝试计算列表(df2.list2)的列中出现列表(df1.list1的每一行)的频率。所有列表仅包含唯一值。List1包含约300.000行,list2包含30.000行。
我有一个有效的代码,但是它的运行速度非常慢(因为我使用的是迭代程序)。我也尝试过itertuples(),但它给了我一个错误(“要解压缩的值太多(预期2)”)。我在网上发现了一个类似的问题:熊猫计算包含在list列中的list的出现。在提到的情况下,此人仅考虑一个列表列中一个列表的出现。但是,我无法解决问题,因此将df1.list1中的每一行都与df2.list2进行了比较。
那就是我的列表的样子(简化):
df1.list1 0 ["a", "b"] 1 ["a", "c"] 2 ["a", "d"] 3 ["b", "c"] 4 ["b", "d"] 5 ["c", "d"] df2.list2 0 ["a", "b" ,"c", "d"] 1 ["a", "b"] 2 ["b", "c"] 3 ["c", "d"] 4 ["b", "c"]
我想提出的是:
df1
list1 occurence 0 ["a", "b"] 2 1 ["a", "c"] 1 2 ["a", "d"] 1 3 ["b", "c"] 3 4 ["b", "d"] 1 5 ["c", "d"] 2
那就是我到目前为止所得到的:
for index, row in df_combinations.iterrows(): df1.at[index, "occurrence"] = df2["list2"].apply(lambda x: all(i in x for i in row['list1'])).sum()
有什么建议可以加快速度吗?提前致谢!
这应该快得多:
df = pd.DataFrame({'list1': [["a","b"], ["a","c"], ["a","d"], ["b","c"], ["b","d"], ["c","d"]]*100}) df2 = pd.DataFrame({'list2': [["a","b","c","d"], ["a","b"], ["b","c"], ["c","d"], ["b","c"]]*100}) list2 = df2['list2'].map(set).tolist() df['occurance'] = df['list1'].apply(set).apply(lambda x: len([i for i in list2 if x.issubset(i)]))
使用您的方法:
%timeit for index, row in df.iterrows(): df.at[index, "occurrence"] = df2["list2"].apply(lambda x: all(i in x for i in row['list1'])).sum()
1个循环,每个循环最多3:3.98 s使用我的:
%timeit list2 = df2['list2'].map(set).tolist();df['occurance'] = df['list1'].apply(set).apply(lambda x: len([i for i in list2 if x.issubset(i)]))
10个循环,最好为3:每个循环29.7 ms
请注意,我已将列表的大小增加了100倍。
编辑
这似乎更快:
list2 = df2['list2'].sort_values().tolist() df['occurance'] = df['list1'].apply(lambda x: len(list(next(iter(())) if not all(i in list2 for i in x) else i for i in x)))
和时间:
%timeit list2 = df2['list2'].sort_values().tolist();df['occurance'] = df['list1'].apply(lambda x: len(list(next(iter(())) if not all(i in list2 for i in x) else i for i in x)))
100个循环,最好为3:每个循环14.8 ms