【问题标题】:Best practice (effiency) data manipulation of pandas big dataframepandas大数据框的最佳实践(效率)数据操作
【发布时间】:2020-05-29 10:22:55
【问题描述】:

我正在处理大型数据集,我想询问更改熊猫数据框df的某些条目的最佳方法@

这是我的代码:

mask = df.P2I.values > c_th
df.loc[mask, 'P1I'] = df.P1I - c_offset
df.loc[mask, 'P3I'] = df.P3I - c_offset
df.loc[mask, 'P2I'] = df.P2I - c_offset
  1. 有没有一种方法可以在一次调用中直接访问这些行列并同时执行三个操作?
  2. 我是否应该将.values 调用到数据帧以进行连续的内存分配来进行减法?

我无法衡量性能,这就是我要问的原因。谢谢大家

【问题讨论】:

  • 请问您为什么无法衡量性能?我认为只是尝试一下将是最好的解决方案! :)
  • 我还在研究如何在使用 python 脚本时正确地做到这一点
  • 如果您无法衡量性能,那您为什么还要寻找优化程序的方法?
  • 计算需要很长时间,所以我正在学习如何优化小块代码和最佳实践以改进代码库

标签: python pandas numpy indexing data-manipulation


【解决方案1】:

在你的情况下你可以这样做:

df.loc[mask, ['P1I', 'P2I', 'P3I']] -= c_offset

如果需要,您还可以对每列使用不同的偏移量,如下所示(就性能而言,它看起来与第一个非常相似):

df.loc[mask, ['P1I', 'P2I', 'P3I']] -= [ c_offset_1, c_offset_2, c_offset_3 ]

但是,如果性能至关重要,那么最好的选择似乎确实是使用 numpy 格式。可能如果您的“数学争论”大于单个减法,这似乎是要走的路:

df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset

注意:OP 在他/她的数据集中测试了这种方法,并提到它实际上比仅使用前一种方法要慢。试图复制这个,但我的电脑在我能够复制之前几乎崩溃了......

我比较了不同方法的一些时间安排:

import pandas as pd
import numpy as np

df = pd.DataFrame({ "P1I": np.random.rand(1000000), 
                    "P2I": np.random.rand(1000000), 
                    "P3I": np.random.rand(1000000) })

c_th = 0.5
c_offset = -1

mask = df.P2I > c_th
%timeit df.loc[ mask, "P1I" ] = df.loc[ mask , "P1I" ] - c_offset; df.loc[ mask, "P2I" ] = df.loc[ mask , "P2I" ] - c_offset; df.loc[ mask, "P3I" ] = df.loc[ mask , "P3I" ] - c_offset
# 77.9 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= c_offset
# 59.3 ms ± 1.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] -= [ c_offset, c_offset, c_offset ]
# 59.5 ms ± 3.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.loc[ mask, ["P1I", "P2I", "P3I"]] = df.loc[ mask, ["P1I", "P2I", "P3I"]].values - c_offset
# 43.6 ms ± 553 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

【讨论】:

  • 感谢您的测试,我的结果与更大的数据集不同。 Numpy 转换比使用 pandas 慢。我想这是由于内存分配比在连续内存空间中操作的优势要慢。
  • 数据帧大小为 63757792 的结果是 df.loc[mask_c_offset, ['P1I', 'P2I', 'P3I']] -= c_offset 比 df.loc[mask_c_offset, ['P1I', 'P2I', 'P3I']].values-c_offset
猜你喜欢
  • 2012-09-01
  • 2015-10-29
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
相关资源
最近更新 更多