我有一个名为"stock_data"的熊猫数据帧,其多索引索引为("日期","股票ID")和"价格"列。行按日期排序,因此对于同一股票,较晚的日期将具有更高的行索引。我想添加一个新列,对于每只股票(即按股票分组)包含一个数字,该数字具有股票价格随时间变化的最大正差,如 max_price - min_price。
为了进一步解释这一点,可以在 O(stocks*rows^2) 中计算出这一点:
for each stock:
max = 0.0
for i in range(len(rows)-1):
for j in range(i+1, len(rows):
if price[j] - price[i] > max:
max = price[j] - price[i]
如何在 pandas 中执行此操作,而无需实际计算每个值并将其分配给数据帧新列的正确位置,就像上面的算法一样(这可以通过排序来改进,但这不是重点)?
到目前为止,我只发现我可以按"StockID"分组:stock_data.groupby(level='Stock')
并选择列stock_data.groupby(level='Stock')['Price']
。但像这样:
stock_data.groupby(level='Stock')['Price'].max() - stock_data.groupby(level='Stock')['Price'].min()
不是我上面描述的,因为没有 max() 必须在 min() 之后的剩余时间。
编辑:接受的解决方案有效。现在我也想知道是否有办法通过最大值与最小值的距离来惩罚该距离,因此较短的增益比差异较大的长期收益更高(因此更受欢迎)。
例如,也许我们可以在 min 之后做 cumsum() 直到最后的一定长度?不知何故?
让我们尝试[::-1]
颠倒顺序,以便能够获得最大值"在未来",然后在groupby
之后cummin
和cummax
。
# sample data
np.random.seed(1)
stock_data = pd.DataFrame({'Price':np.random.randint(0,100, size=14)},
index=pd.MultiIndex.from_product(
[pd.date_range('2020-12-01', '2020-12-07', freq='D'),
list('ab')],
names=['date','stock'])
)
假设日期按时间排序,您可以执行以下操作:
stock_data['diff'] = (df.loc[::-1, 'Price'].groupby(level='stock').cummax()
- df.groupby(level='stock')['Price'].cummin())
print(stock_data)
Price diff
date stock
2020-12-01 a 37 42
b 12 59
2020-12-02 a 72 42
b 9 62
2020-12-03 a 75 42
b 5 66
2020-12-04 a 79 42
b 64 66
2020-12-05 a 16 60
b 1 70
2020-12-06 a 76 60
b 71 70
2020-12-07 a 6 0
b 25 24