我正在尝试将我的一些 R 脚本“翻译”为 Python,但我注意到,在 Python 中处理数据帧比在 R 中处理要慢得多,例如根据某些条件提取细胞。
我做了一些调查,这是在 Python 中查找特定值所需的时间:
import pandas as pd
from timeit import default_timer as timer
code = 145896
# real df is way bigger
df = pd.DataFrame(data={
'code1': [145896, 800175, 633974, 774521, 416109],
'code2': [100, 800, 600, 700, 400],
'code3': [1, 8, 6, 7, 4]}
)
start = timer()
for _ in range(100000):
desired = df.loc[df['code1']==code, 'code2'][0]
print(timer() - start) # 19.866242500000226 (sec)
在 R 中:code <- 145896
df <- data.frame("code1" = c(145896, 800175, 633974, 774521, 416109),
"code2" = c(100, 800, 600, 700, 400),
"code3" = c(1, 8, 6, 7, 4))
start <- Sys.time()
for (i in 1:100000) {
desired <- df[df$code1 == code, "code2"]
}
print(Sys.time() - start) # Time difference of 1.140949 secs
我对 Python 比较陌生,我可能遗漏了一些东西。有什么方法可以加快这个过程吗?也许将这个脚本转移到 Python 的整个想法毫无意义?在其他操作中,Python 更快(即处理字符串),并且一旦需要处理数据帧,在两个或多个脚本之间跳转会非常不方便。请问这有什么帮助吗?更新
真实脚本块迭代初始数据框的行(相当大,500-1500k 行),并创建一个新的行,其中包含来自原始列“code1”的值和来自另一个数据框的与其对应的代码,以及新创建的许多其他值。我相信,我可以用图片说明:
![enter image description here](https://i.stack.imgur.com/89h2R.png)
在脚本的后面,我还需要根据不同的条件在循环中搜索特定的值。所以搜索的速度是必不可少的。
最佳答案
由于您要选择 单例来自 DataFrame 的值(value) 您可以采取一些措施来提高性能。
.item()
而不是 [0]
,特别是对于较小的 DataFrames 有一个很小但不错的改进。 ][
”,但令人担忧的只是链式分配,而不是链式选择。 numpy
会更快。 下面是选择数据的不同方法的时间说明[下面每种方法都有自己的方法]。使用
numpy
是迄今为止最快的,尤其是对于像您的示例中那样较小的 DataFrame。对于那些,它将比您选择数据的原始方式快 20 倍以上,查看您与 R 的初始比较应该使其比在 R 中选择数据略快。随着 DataFrames 变得更大,numpy 解决方案的相对性能是不是很好,但它仍然是最快的方法(如图所示)。import perfplot
import pandas as pd
import numpy as np
def DataFrame_Slice(df, code=0):
return df.loc[df['code1'] == code, 'code2'][0]
def DataFrame_Slice_Item(df, code=0):
return df.loc[df['code1'] == code, 'code2'].item()
def Series_Slice_Item(df, code=0):
return df['code2'][df['code1'] == code].item()
def with_numpy(df, code=0):
return df['code2'].to_numpy()[df['code1'].to_numpy() == code].item()
perfplot.show(
setup=lambda N: pd.DataFrame({'code1': range(N),
'code2': range(50, N+50),
'code3': range(100, N+100)}),
kernels=[
lambda df: DataFrame_Slice(df),
lambda df: DataFrame_Slice_Item(df),
lambda df: Series_Slice_Item(df),
lambda df: with_numpy(df)
],
labels=['DataFrame_Slice', 'DataFrame_Slice_Item', 'Series_Slice_Item', 'with_numpy'],
n_range=[2 ** k for k in range(1, 21)],
equality_check=np.allclose,
relative_to=3,
xlabel='len(df)'
)
![enter image description here](https://i.stack.imgur.com/yZ8hy.png)
关于python - 在 Pandas DataFrame 中查找值的更快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68490691/