SO上有数百个关于移动平均线的示例,但是我的情况略有不同,我正在寻找一些Pythonic解决方案:
要求:
给定一个窗口(例如5),我想为列target
计算一个修改后的移动平均值,并将结果转储到一个新列中,例如MA
:
对于从0〜3(前四个)的索引,请使用SUM(0〜target
的索引)/(index +1);
对于索引> =窗口-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:无法使用这些索引器进行切片索引
下次尝试:
我没有技巧,所以我决定使用普通的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:仅整数标量数组可以转换为标量索引
无论如何,我想知道是否有一种优雅的方法来做到这一点,并且总的来说,是否存在一种通过指数函数应用计算值的优雅方法(例如,如果func_index(index )<1,000,值应为func_value(另一列* 10))
答案 0 :(得分:1)
如果要处理库存数据,可以尝试stockstats。 这是示例代码:
stock = StockDataFrame.retype(pd.read_csv('stock.csv'))
stock['close_5_sma']