【问题标题】:Speed of pandas df.loc[x, 'column']pandas df.loc[x, 'column'] 的速度
【发布时间】:2017-07-19 16:28:48
【问题描述】:

我有一个大约 100 行的 pandas DataFrame,我需要从其中以有效的方式从给定索引的列中选择值。目前我正在为此使用df.loc[index, 'col'],但这似乎相对较慢:

df = pd.DataFrame({'col': range(100)}, index=range(100))    
%timeit df.loc[random.randint(0, 99), 'col']
#100000 loops, best of 3: 19.3 µs per loop

似乎更快(大约 10 倍)的方法是将数据框转换为字典,然后查询:

d = df.to_dict()    
%timeit d['col'][random.randint(0, 99)]
#100000 loops, best of 3: 2.5 µs per loop

有没有办法使用普通数据框方法获得类似的性能,而无需显式创建字典?我应该使用.loc以外的东西吗?

或者这只是我最好使用此解决方法的情况?

【问题讨论】:

  • 这里有几个选择:df.get_value(random.randint(0, 99), 'col')(最快)、df['col'].values[random.randint(0, 99)](假设位置和标签相同)和df.at[random.randint(0, 99), 'col'],但这部分通常不是你应该关注的部分在进行代码优化时。可能您在循环中执行此操作,对吗?
  • 同意@ayhan,纯粹的 Python 字典几乎肯定会比 Pandas 方法更快地按索引读取标量值,因为 Pandas 方法严重过载,并且每个方法都包含多个字典访问。性能提升的最大潜力在于使用矢量化函数而不是 Python 循环。
  • 不幸的是,矢量化在这里并不是一个真正的选择,因为我需要逐行处理文件并且无法将所有数据保存在内存中。在我的情况下,从.loc 切换到dict 似乎确实会导致整个循环的速度提高大约 5-10 倍。

标签: python pandas


【解决方案1】:

dict 确实似乎是最快的选择:

df_dict = df.to_dict()
df_numpy = np.array(df)
print(timeit.timeit("df.loc[random.randint(0, 99), 'col']", number = 100000, globals=globals()))
print(timeit.timeit("df.get_value(random.randint(0, 99), 'col')", number = 100000, globals=globals()))
print(timeit.timeit('df_numpy[df_numpy[random.randint(0, 99)]]', number=100000, globals=globals()))
print(timeit.timeit("df_dict['col'][random.randint(0, 99)]", number = 100000, globals=globals()))

结果:

4.859706375747919
1.8850274719297886
1.4855970665812492
0.6550335008651018

【讨论】:

    【解决方案2】:

    如果效率是一个需要考虑的因素,Numpy 数组可能是比 pandas 数据框更好的选择。我尝试重现您的示例以衡量效率比较:

    import numpy as np
    import pandas as pd
    import timeit, random
    
    df = pd.DataFrame({'col': range(100)}, index=range(100)) 
    print(timeit.timeit('df.loc[random.randint(0, 99), "col"]', number=10000, globals=globals()))
    
    ds_numpy = np.array(df)
    print(timeit.timeit('ds_numpy[ds_numpy[random.randint(0, 99)]]', number=10000, globals=globals()))
    

    结果:

    $ python test_pandas_vs_numpy.py 
    0.1583892970229499
    0.05918855100753717
    

    在这种情况下,看起来比在 pandas 数据帧上使用 Numpy 数组在性能方面更有优势。

    参考:1

    【讨论】:

    • 谢谢 - 虽然这是对 .loc 的改进,但它似乎仍然比使用字典慢得多(大约 2-3 倍)。
    猜你喜欢
    • 2016-10-11
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 2021-09-27
    相关资源
    最近更新 更多