python - 在 Pandas DataFrame 中查找值的更快方法?

标签 python r pandas dataframe filtering

我正在尝试将我的一些 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
在脚本的后面,我还需要根据不同的条件在循环中搜索特定的值。所以搜索的速度是必不可少的。

最佳答案

由于您要选择 单例来自 DataFrame 的值(value) 您可以采取一些措施来提高性能。

  • 使用 .item()而不是 [0] ,特别是对于较小的 DataFrames 有一个很小但不错的改进。
  • 屏蔽很浪费整个数据帧 只是为了然后选择一个已知的系列。而是仅屏蔽系列并选择值。尽管您可能会想“哦,这是链式的——被禁止的 ][”,但令人担忧的只是链式分配,而不是链式选择。
  • 使用 numpy .由于索引和调整,Pandas 有很多开销。但是您只想从矩形数据结构中选择一个值,因此下拉到 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

    关于python - 在 Pandas DataFrame 中查找值的更快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68490691/

    相关文章:

    python - 在 Windows 7 上安装 flask ?

    R:使用公式绘制矩阵列

    javascript - 需要替换 Shiny R renderDataTable 中的默认 "No data available in table"消息

    python-3.x - 如何根据唯一字符串值将 pandas 数据帧拆分为多个数据帧而不聚合

    python - 使用 Python 连接到 Amazon RDS Postgresql 数据库时出错

    python - 在不使用 Eval 的情况下将字符串转换为 Python 中的列表?

    r - R 中的 Azure PUT Blob 身份验证失败

    python - 合并两个日期时间索引的 pandas.dataframe 对象

    Python Pandas 矩阵乘法 多项运算合二为一

    python - 在 Python pandas 中将数据映射到另一年的同一工作日