SO 上有数百个关于 Pandas 移动平均线的示例,但我的情况略有不同,我正在寻找一些 Pythonic 解决方案:
要求:
给定一个窗口,比如 5,我想计算 coumn target
的修改后的移动平均线,并将结果转储到一个新列中,比如 MA
:
对于从 0~3(前四个)的索引,使用 SUM(0~index of target
)/(index + 1);
对于 index >= window - 1(在本例中为 4),它是一个普通的 MA(5)。我假设 MA(5) 从第 5 个元素开始。
我尝试过的:
首先我知道我可以使用:
df[maname] = df.rolling(window=win)[target].mean()
计算正常的 MA(win) 并转储到 maname
列。
然后我尝试了其他几种方法,但都不起作用:
df[maname] = df[target][:df.index + 1].sum() / (df.index + 1) if df.index < win else df.rolling(window=win)[target].mean()
这给出了一个错误,我意识到这在 pandas
中是不明确的。
下一个:
df[maname] = 0
df[maname][df.index<=win] = df[target][:df.index + 1].sum() / (df.index + 1)
df[maname][df.index>win] = df.rolling(window=win)[target].mean()
错误:
TypeError: cannot do slice indexing on with these indexer
下次尝试:
我没有技巧所以我决定使用普通的 C++ 方法:遍历索引(这个算法实际上与移动平均线不同,但这不是我现在的问题)
for idx in df.index:
loop = 0
while loop <= idx:
df[maname].iloc[idx] = df[maname].iloc[idx] + df[target].iloc[loop]
loop = loop + 1
if idx < win:
df[maname].iloc[idx] = df[maname].iloc[idx] / (idx + 1)
else:
df[maname].iloc[idx] = df[maname].iloc[idx] / win
但令人惊讶的是,我的新列的所有值都是零!我不知道出了什么问题。 编辑 一位编辑者提醒我整数是不可变的,所以我知道为什么它全为零,而且这是非常低效的。
最近的尝试:
我什至尝试硬编码很多东西,但这似乎超出了我的能力范围......
for idx in range(0, 23):
loop = 0
while loop <= idx:
dfToWrite.at[idx, 'MA'] = dfToWrite.at[idx, 'MA'] + 5
loop = loop + 1
if idx < 5:
dfToWrite.at[idx, 'MA'] = dfToWrite.at[idx, 'MA'] / (idx + 1)
else:
dfToWrite.at[idx, 'MA'] = dfToWrite.at[idx, 'MA'] / 5
错误:
TypeError: only integer scalar arrays can be converted to a scalar index
无论如何,我想知道是否有一种优雅的方法可以做到这一点,一般来说,是否有一种优雅的方法可以通过索引函数应用计算值(例如,如果 func_index(index ) < 1,000,值应该是 func_value(另一列 * 10))
最佳答案
如果你处理的是股票数据,你可以给stockstats一试。 这是示例代码:
stock = StockDataFrame.retype(pd.read_csv('stock.csv'))
stock['close_5_sma']
关于python - 如何计算 Python pandas 数据框的修改后移动平均线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54068164/