如何高效计算DataFrame中的delta?求替代itertuples的方案
问题描述
我需要计算delta并已完成实现,但当前使用了itertuples方法,希望避免使用该方式。请问是否存在更高效的实现方案?以下是我的实现代码及输出:
原实现代码
from numpy import append, around, array, float64 from numpy.random import uniform from pandas import DataFrame matrix = around(a=uniform(low=1.0, high=50.0, size=(10, 2)), decimals=2) points = DataFrame(data=matrix, columns=['x', 'y'], dtype='float64') x_column = points.columns.get_loc('x') y_column = points.columns.get_loc('y') x_delta = array(object=[], dtype=float64) y_delta = array(object=[], dtype=float64) for row, iterator in enumerate(iterable=points.itertuples(index=False, name='Point')): if row == 0: x_delta = append(arr=x_delta, values=0.0) y_delta = append(arr=y_delta, values=0.0) else: x_delta = append(arr=x_delta, values=iterator.x / points.iat[row - 1, x_column] - 1) y_delta = append(arr=y_delta, values=iterator.y / points.iat[row - 1, y_column] - 1) x_delta = around(a=x_delta, decimals=2) y_delta = around(a=y_delta, decimals=2) points.insert(loc=points.shape[1], column='x_delta', value=x_delta) points.insert(loc=points.shape[1], column='y_delta', value=y_delta) print(points)
原输出结果
x y x_delta y_delta 0 26.08 1.37 0.00 0.00 1 8.34 6.82 -0.68 3.98 2 38.42 45.20 3.61 5.63 3 3.59 33.12 -0.91 -0.27 4 42.94 11.06 10.96 -0.67 5 31.99 17.38 -0.26 0.57 6 4.29 17.46 -0.87 0.00 7 19.68 22.28 3.59 0.28 8 27.55 12.98 0.40 -0.42 9 40.23 9.60 0.46 -0.26
高效实现方案
当然有!你的当前实现依赖循环+numpy.append,这两个操作其实都挺影响效率的——尤其是append每次都会创建新数组,数据量大的时候内存开销会非常高。咱们可以直接用pandas内置的向量化操作来实现,完全不需要循环,代码更简洁还快得多。
优化后的代码
import numpy as np import pandas as pd # 生成测试数据(和原代码逻辑一致) matrix = np.around(np.random.uniform(low=1.0, high=50.0, size=(10, 2)), decimals=2) points = pd.DataFrame(matrix, columns=['x', 'y'], dtype='float64') # 核心:用shift()获取上一行数据,直接计算delta points['x_delta'] = np.around(points['x'] / points['x'].shift(1) - 1, decimals=2) points['y_delta'] = np.around(points['y'] / points['y'].shift(1) - 1, decimals=2) # 第一行没有上一行数据,手动设为0.0 points.loc[0, ['x_delta', 'y_delta']] = 0.0 print(points)
为什么这个方案更好?
- 速度快:完全利用pandas的向量化运算,比循环快几个数量级,数据量越大优势越明显
- 内存高效:避免了
numpy.append反复创建新数组的内存浪费 - 可读性强:代码行数大幅减少,逻辑一目了然,后期维护成本低
如果是处理超大规模数据集,还可以结合numpy的diff等方法进一步优化,但上面的实现已经足够应对绝大多数场景啦。
内容的提问来源于stack exchange,提问作者Hazan
相关产品推荐
相关产品推荐

