当前位置: 首页 > 面试题库 >

更快的替代方案

曾修真
2023-03-14
问题内容

我知道这个话题已经解决了上千次。但是我找不到解决办法。

我正在尝试计算列表(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



 类似资料:
  • 问题内容: 为了提高其性能,我一直在使用VisualVM采样器对我的一个应用程序进行性能分析,最小采样周期为20ms。根据探查器,主线程在该方法中花费了将近四分之一的CPU时间。 我正在与该模式一起使用,以将数字“转换” 为正好有六个十进制数字的字符串表示形式。我知道这种方法相对昂贵并且 被 多次调用,但是我对这些结果感到有些惊讶。 这种采样分析器的结果在多大程度上准确?我将如何验证它们-最好不借

  • 问题内容: 我有一个3d数组,其中填充了从0到N的整数。我需要一个与该数组等于1、2、3,… N的位置对应的索引列表。我可以使用np.where进行如下操作: 但这很慢。根据这个问题 快速python numpy在哪里功能? 应该可以大大加快索引搜索的速度,但是我无法将那里提出的方法转移到我获取实际索引的问题上。加快上述代码的最佳方法是什么? 作为附加组件:我想稍后存储索引,使用np.ravel_

  • 问题内容: replace方法返回一个字符串对象而不是替换给定字符串的内容这一事实有点让人费解(但是,当您知道字符串在Java中是不可变的时,这是可以理解的)。通过在某些代码中使用深度嵌套的替换,我的性能受到了重大影响。有什么我可以替换的东西可以使它更快吗? 问题答案: 这就是StringBuilder的目的。如果要进行很多操作,请在上进行操作,然后在需要时将其转换为。 因此描述: “可变的字符序

  • Python的http.server(或Python 2的SimpleHTTPServer)是从命令行提供当前目录内容的一种很好的方式:

  • 问题内容: 我正在制作一个程序,要求至少每秒捕获24个屏幕截图。目前,使用下面的代码,我每94毫秒仅获得1个,因此大约为10毫秒。 我不想使用任何第三方库,因为我试图将其保持尽可能小,但是如果我希望获得显着的性能提升,我会愿意的。我也试图保持该平台独立,但是,如果确实能够显着提高性能,我愿意将其限于Windows。 编辑:我现在也尝试了两种不同的方法;使用在oracles网站上找到的代码段,并在下

  • null 在当前的JVMTI代理中已经被大量使用,所以我正在寻找一种更快的方法来获取标记或实现我自己的机制,同时保持在C端。