嗨,我有一个面板数据集,看起来像
require 'csv'
table = CSV.table('file_name.csv')
transformed_into_hash = table.map { |row| row.to_hash }
File.open("file_name.yaml", "w") do |f|
f.puts transformed_into_hash.to_yaml
end
我想计算每天每一只股票的stock date time spread1 weight spread2
VOD 01-01 9:05 0.01 0.03 ...
VOD 01-01 9.12 0.03 0.05 ...
VOD 01-01 10.04 0.02 0.30 ...
VOD 01-02 11.04 0.02 0.05
... ... ... .... ...
BAT 01-01 0.05 0.04 0.03
BAT 01-01 0.07 0.05 0.03
BAT 01-01 0.10 0.06 0.04
加权平均值。我可以将解决方案分为几个步骤。即,我可以应用spread1
和groupby
函数来获取数据框1中每一天每一股票的点差1 *权重之和,然后计算数据框2中每一天每一只股票的权重之和。之后,agg
将获得两个数据集,并获得spread1的加权平均值。
我的问题是,有什么简单的方法可以计算出spread1的加权平均值吗?我也有spread2,spread3和spread4。所以我想写更少的代码。谢谢
答案 0 :(得分:1)
IIUC,您需要将结果transform
恢复到原始状态,但是将.transform
与依赖于两列的输出配合使用非常棘手。我们编写了自己的函数,在其中传递了一系列扩展s
和原始DataFrame df
,因此我们也可以使用权重:
import numpy as np
def weighted_avg(s, df):
return np.average(s, weights=df.loc[df.index.isin(s.index), 'weight'])
df['spread1_avg'] = df.groupby(['stock', 'date']).spread1.transform(weighted_avg, df)
stock date time spread1 weight spread1_avg
0 VOD 01-01 9:05 0.01 0.03 0.020526
1 VOD 01-01 9.12 0.03 0.05 0.020526
2 VOD 01-01 10.04 0.02 0.30 0.020526
3 VOD 01-02 11.04 0.02 0.05 0.020000
4 BAT 01-01 0.05 0.04 0.03 0.051000
5 BAT 01-01 0.07 0.05 0.03 0.051000
6 BAT 01-01 0.10 0.06 0.04 0.051000
如果需要多列:
gp = df.groupby(['stock', 'date'])
for col in [f'spread{i}' for i in range(1,5)]:
df[f'{col}_avg'] = gp[col].transform(weighted_avg, df)
或者,如果您不需要转换回去并且每个股票日期都想要一个值:
def my_avg2(gp):
avg = np.average(gp.filter(like='spread'), weights=gp.weight, axis=0)
return pd.Series(avg, index=[col for col in gp.columns if col.startswith('spread')])
### Create some dummy data
df['spread2'] = df.spread1+1
df['spread3'] = df.spread1+12.1
df['spread4'] = df.spread1+1.13
df.groupby(['stock', 'date'])[['weight'] + [f'spread{i}' for i in range(1,5)]].apply(my_avg2)
# spread1 spread2 spread3 spread4
#stock date
#BAT 01-01 0.051000 1.051000 12.151000 1.181000
#VOD 01-01 0.020526 1.020526 12.120526 1.150526
# 01-02 0.020000 1.020000 12.120000 1.150000