在 pandas 中寻找加速此应用功能的方法
Looking for a way to speed up this apply function in pandas
我目前正在处理一个 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)
现在的问题是dataframe中有超过200k行,多列都有这个问题,所以这个方法会花费很多时间(每列~1.5s)。
下面是一个可重现的例子
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
)
感谢任何建议,谢谢!
在你的情况下ast
import ast
df['column1'] = df['column1'].map(lambda x : ast.literal_eval(x) if x == x else x)
有一些关于这个主题的讨论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 在评论中的建议):
%%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
我目前正在处理一个 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)
现在的问题是dataframe中有超过200k行,多列都有这个问题,所以这个方法会花费很多时间(每列~1.5s)。
下面是一个可重现的例子
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
)
感谢任何建议,谢谢!
在你的情况下ast
import ast
df['column1'] = df['column1'].map(lambda x : ast.literal_eval(x) if x == x else x)
有一些关于这个主题的讨论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 在评论中的建议):
%%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