【问题标题】:Looking for a way to speed up this apply function in pandas寻找一种方法来加速熊猫中的这个应用功能
【发布时间】:2021-12-25 19:02:55
【问题描述】:

我目前正在处理一个 csv 文件,该文件包含同时具有 na 和 list 值的列。当我读入数据时,列表值变为字符串值,即 [1, 2, 3] 变为“[1, 2, 3]”。我曾尝试使用 ast.literal_eval 使用转换器读取数据,但不幸的是,由于数据中存在 na 值,此方法不起作用。

我通过将以下函数应用于存在此问题的列来解决此问题。

import numpy as np

def string_to_list(row_value):
    if row_value is np.nan:
        return np.nan

    else:
        return eval(row_value)

现在的问题是数据框中有超过 200k 行,并且多个列存在此问题,因此此方法将花费大量时间(每列约 1.5 秒)。

下面是一个可重现的例子

import pandas as pd

column1 = [np.nan, "[1, 2, 3]", "[3, 2, 1]"] * 100000
df = pd.DataFrame(
    {
        'column1': column1
    }
)

df['column1'].apply(lambda x: string_to_list(x))

经过一些研究,我发现很多帖子都说向量化是一种将函数应用于列的更快方法,但我不确定如何在我的案例中应用它。我尝试了以下方法,但我不确定如何指定将函数运行到条件语句为假的索引。

np.where(
    pd.isna(x),
    x,
    string_to_list(x) #Confused on how to pass argument in here where the conditional statements results to False
)

感谢任何建议,谢谢!

【问题讨论】:

    标签: python pandas vectorization apply


    【解决方案1】:

    关于这个话题here有一些讨论,这表明使用以下(更不可读的)函数更快:

    def string_to_list2(row_value):
        if row_value is np.nan:
            return np.nan
        else:
            return list(map(str.strip, row_value.strip('][').replace('"','').split(',')))
    

    当我用 1000 行重新创建您的 df 时,情况似乎确实如此(感谢 @HarryPlotter 在 cmets 中的建议):

    %%timeit 
    df['column1'].apply(string_to_list)
    # 1000 loops, best of 5: 1.75 ms per loop
    
    %%timeit 
    df['column1'].apply(string_to_list2)
    # 1000 loops, best of 5: 555 µs per loop
    

    【讨论】:

    • 不错!使用map 而不是apply 应该会更快一点。另请注意(和 OP)lambda 在这里是多余的,lambda x: string_to_list(x) 可以简化为 string_to_list
    【解决方案2】:

    你的情况是ast

    import ast 
    
    df['column1'] = df['column1'].map(lambda x : ast.literal_eval(x)  if x == x else x)
    

    【讨论】:

    • OP 注释。永远不要在代码中使用eval。除非您真的、真的知道自己在做什么,否则您将面临巨大的安全漏洞。
    猜你喜欢
    • 2020-01-07
    • 2015-09-30
    • 2014-01-09
    • 2016-05-22
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多