如何快速实现DataFrame相邻行滚动求和?替代低效Python循环方案
高效计算DataFrame相邻行求和的方法
你当前通过Python循环实现DataFrame相邻行(含当前行前后各forecast行)求和的方式,在数据量大时速度会明显受限。可以利用Pandas的矢量化操作替代循环,大幅提升效率,以下是两种最优方案:
原实现代码
import pandas as pd dictionary = { 'In':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] } df = pd.DataFrame(dictionary) forecast = 1 temp = [] for i in range(len(df["In"])): temp = temp + [sum(df["In"][i - forecast : i + forecast + 1])] df["Out"] = temp df["Out"][:forecast] = None df["Out"][-forecast:] = None print(df)
方案一:滚动窗口求和(Rolling Sum)
利用rolling()方法创建大小为2*forecast+1的滑动窗口,直接计算窗口内的和,这是Pandas中处理这类滑动聚合的标准高效方式:
import pandas as pd dictionary = { 'In':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] } df = pd.DataFrame(dictionary) forecast = 1 # 计算滚动窗口和,窗口大小=前后各forecast行+当前行 window_size = 2 * forecast + 1 df['Out'] = df['In'].rolling(window=window_size, center=True).sum() print(df)
center=True:将窗口的中心对齐到当前行,刚好对应你需求的i-forecast到i+forecast的范围- 首尾无法形成完整窗口的行自动填充
NaN,无需手动赋值,和原代码结果完全一致
方案二:移位相加(Shift + Sum)
如果需要更灵活的控制,可以通过shift()方法分别获取前后forecast行的数据,再与当前行求和:
import pandas as pd dictionary = { 'In':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] } df = pd.DataFrame(dictionary) forecast = 1 # 取前forecast行、当前行、后forecast行相加 df['Out'] = df['In'].shift(-forecast) + df['In'] + df['In'].shift(forecast) # 首尾forecast行手动设为NaN(移位后首尾会自动出现NaN,此步骤可省略) df.loc[:forecast-1, 'Out'] = None df.loc[-forecast:, 'Out'] = None print(df)
这种方法在窗口逻辑复杂时更易调整,同样是矢量化操作,效率远高于循环。
效率对比
对于100万行的DataFrame,循环方法需要数十秒,而上述两种矢量化方法仅需毫秒级即可完成计算,差距非常明显。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

