计算月份正弦余弦触发MemoryError的问题排查与优化求助
问题分析与优化方案
核心问题1:apply逐行处理的低效与变量引用错误
你当前的代码用apply(lambda row: get_sin(month, 12), axis=1)存在两个致命问题:
- 变量引用错误:lambda里直接用了
month,而非row['month']——这会把整个df_ufvdate['month']Series传入get_sin函数,而非每行的单个月份值,瞬间占用大量内存触发MemoryError。 - 逐行循环的低效:
apply(axis=1)本质是Python级别的逐行循环,对5万条数据来说,不仅速度慢,还会生成大量临时对象,加剧内存消耗。
核心问题2:month字段的类型异常
df_ufvdate.info()显示month为int64,但describe()返回float64,原因是字段存在缺失值(NaN)。pandas原生int64类型无法存储NaN,执行astype('int64')时,若原字段有NaN,pandas会自动转为Nullable Integer类型(Int64,大写I),但describe()计算时会将其转为float64兼容NaN,属于正常行为。可通过df_ufvdate['month'].isna().sum()检查缺失值数量。
优化方案
方案1:向量化计算替代apply(最优解)
直接对整个month列执行向量化的正弦/余弦计算,这是pandas/numpy原生高效操作,内存占用极低,速度是逐行循环的几十倍:
import numpy as np # 计算月份正弦值 df_ufvdate['month_sine'] = np.sin(df_ufvdate['month'] * (2 * np.pi / 12)) # 计算月份余弦值 df_ufvdate['month_cosine'] = np.cos(df_ufvdate['month'] * (2 * np.pi / 12))
方案2:修复apply的变量引用(不推荐,仅作错误修正)
若一定要用apply,需修正lambda的变量引用,但效率远低于向量化:
# 修正为row['month'],指向每行的月份值 df_ufvdate['month_sine'] = df_ufvdate.apply(lambda row: get_sin(row['month'], 12), axis=1)
方案3:处理month字段的缺失值
若month存在NaN,计算会得到NaN结果,可按需处理:
- 填充缺失值:
df_ufvdate['month'] = df_ufvdate['month'].fillna(0).astype('int64')(0代表非月份,或按业务逻辑填充其他值) - 过滤缺失值:
df_ufvdate = df_ufvdate.dropna(subset=['month'])
内容的提问来源于stack exchange,提问作者NigelBlainey
相关产品推荐
相关产品推荐

