这是我的数据框。 有一个日期索引,每个日期有 4 个符号。 我想循环每个符号的每个日期。 “数量”列是根据前一个日期的“tot_value”计算的。 “tot_value”是针对特定日期计算的,并且对于所有交易品种都是通用的。每个日期的每个符号的“值”列都不同。
这是我在这里使用转变的方式的问题。它不引用先前的日期值。 相反,它使用我在填充数据帧时使用的 tot_value 的默认值。 然而,在最终结果中,tot_value 计算正确。
我是 python 新手,希望对这个循环有任何帮助。
这是我的代码。
import pandas as pd
# create the dataframe
data = {'symbol': ['A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D'],
'date':['05/06/2024','05/06/2024','05/06/2024','05/06/2024',
'05/07/2024','05/07/2024','05/07/2024','05/07/2024',
'05/08/2024','05/08/2024','05/08/2024','05/08/2024',
'05/09/2024','05/09/2024','05/09/2024','05/09/2024'],
'tot_value': [1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000],
'mult': [1, 1.1, 1.2, 1.3,1.4, 1.5, 1.6, 1.7,1.8, 1.9, 2, 2.1,2.2, 2.3, 2.4, 2.5],
'quantity': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
'value': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
}
df = pd.DataFrame(data)
df.set_index(['date'], inplace = True)
symbols = df['symbol'].unique()
# loop by date index and symbol
for ind in df.index.unique():
for symbol in symbols:
df['quantity'][ind] = df['tot_value'][ind].shift(1) * df['mult'][ind]
df['value'][ind] = df['quantity'][ind] * 5
g = df.groupby('date')['value'].sum()
df['tot_value'][ind] = g.sum()
df
这是预期的输出。 计算:
日期 = 5/6 之前的日期没有 tot_value,因此数量列为 NaN。因此该值也是 NaN。 tot_value = 默认值 1,000。
日期 = 5/7 前一个日期的 tot_value = 1,000。 该日期的数量基于 tot_value 1,000。 一旦计算出数量,价值计算就很简单了。 5/7 的 tot_value = 5/6 的 tot_value + 5/7 上 4 个符号的值之和。 5/7 的总值 = 1,000 + sum(7,000 + 7,500 + 8,000 + 8,500) = 32,000
日期 = 5/8 前一个日期的 tot_value = 32,000。 该日期的数量基于 tot_value 32,000。 一旦计算出数量,价值计算就很简单了。 5/8 的 tot_value = 5/7 的 tot_value + 5/8 上 4 个符号的值之和。 5/8 的总值 = 32,000 + sum(288,000 + 304,000 + 320,000 + 336,000) = 1,280,000。
符号 | tot_value(预期) | 多 | 数量(预计) | 值(预期) | |
---|---|---|---|---|---|
日期 | |||||
2024 年 5 月 6 日 | A | 1,000 | 1 | NaN | NaN |
2024 年 5 月 6 日 | B | 1,000 | 1.1 | NaN | NaN |
2024 年 5 月 6 日 | C | 1,000 | 1.2 | NaN | NaN |
2024 年 5 月 6 日 | D | 1,000 | 1.3 | NaN | NaN |
2024 年 5 月 7 日 | A | 32,000 | 1.4 | 1,400 | 7,000 |
2024 年 5 月 7 日 | B | 32,000 | 1.5 | 1,500 | 7,500 |
2024 年 5 月 7 日 | C | 32,000 | 1.6 | 1,600 | 8,000 |
2024 年 5 月 7 日 | D | 32,000 | 1.7 | 1,700 | 8,500 |
2024 年 5 月 8 日 | A | 1,280,000 | 1.8 | 57,600 | 288,000 |
2024 年 5 月 8 日 | B | 1,280,000 | 1.9 | 60,800 | 304,000 |
2024 年 5 月 8 日 | C | 1,280,000 | 2 | 64,000 | 320,000 |
2024 年 5 月 8 日 | D | 1,280,000 | 2.1 | 67,200 | 336,000 |
2024 年 5 月 9 日 | A | 61,440,000 | 2.2 | 2,816,000 | 14,080,000 |
2024 年 5 月 9 日 | B | 61,440,000 | 2.3 | 2,944,000 | 14,720,000 |
2024 年 5 月 9 日 | C | 61,440,000 | 2.4 | 3,072,000 | 15,360,000 |
2024 年 5 月 9 日 | D | 61,440,000 | 2.5 | 3,200,000 | 16,000,000 |
你的计算本质上是迭代的,这个循环是一种有效的方法。
但这不是经典的推送操作类型。
假设数据按日期排序,然后按符号排序,一个选项是循环遍历
groupby
:
tot = df['tot_value'].iloc[0]
dates = df.index.unique()
for d, g in df.loc[dates[1]:].groupby('date', sort=False):
qty = tot*g['mult']
val = qty*5
tot = val.sum()
df.loc[d, 'quantity'] = qty
df.loc[d, 'value'] = val
df.loc[d, 'tot_value'] = tot