我有一个约300万行的数据框,看起来像:
date size price
0 2018-08-01 100 220
1 2018-08-01 110 245
2 2018-08-01 125 250
3 2018-08-02 110 210
4 2018-08-02 120 230
5 2018-08-02 150 260
6 2018-08-03 115 200
对于每一行,它是一项物料的事务。我们有交易日期,物品的大小和价格。
现在,我想添加一列avg_price,这样,一个交易/行的avg_price是最后一天的 个交易的k个交易的平均值。最接近的大小(非常类似于k个最近邻居的大小)。
例如,当k = 2时,上面最后一行的avg_price应该为(210 + 230)/ 2 = 220,因为2个最接近的交易的大小分别为110和120,价格分别为210和230。>
预期输出应为:
date size price avg_price
0 2018-08-01 100 220 NA
1 2018-08-01 110 245 NA
2 2018-08-01 125 250 NA
3 2018-08-02 110 210 (220+245)/2
4 2018-08-02 120 230 (245+250)/2
5 2018-08-02 150 260 (245+250)/2
6 2018-08-03 115 200 (210+230)/2
我写了一个for循环来遍历每一行,首先选择最后一天的所有交易,然后按大小差异排序并计算前k个项目的平均值。但是,正如预期的那样,这非常慢。有人可以指出一种更“矢量化”的方法吗?谢谢。
更新:每天的交易数量不固定,大约300。
答案 0 :(得分:1)
我将dfa
称为原始数据帧。首先在dfb
中创建您需要的数据,以供以后使用merge_asof
k = 2 # should work for any number
dfb = dfa.copy()
dfb = dfb.sort_values(['date','size']) #actually need in dfa too
# get the k-mean
dfb['avg_price'] = dfb.groupby('date').price.rolling(k).mean().values
#to look for the k nearest sizes in merge_asof
dfb['size'] = dfb.groupby('date')['size'].rolling(k).mean().values
# add one business day to shift all the date
dfb['date'] = dfb['date'] + pd.tseries.offsets.BDay()
dfb = dfb.dropna().drop('price',1)
dfb['size'] = dfb['size'].astype(int) #needed for the merge_asof
print (dfb)
date size avg_price
1 2018-08-02 105 232.5
2 2018-08-02 117 247.5
4 2018-08-03 115 220.0
5 2018-08-03 135 245.0
您可以通过merge_asof
和date
使用nearest size
(sort_values
是使用该方法所必需的):
dfa = (pd.merge_asof(dfa.sort_values('size'), dfb.sort_values('size'),
on='size',by='date',direction='nearest')
.sort_values(['date','size']).reset_index(drop=True))
结果是dfa
:
date price size avg_price
0 2018-08-01 220 100 NaN
1 2018-08-01 245 110 NaN
2 2018-08-01 250 125 NaN
3 2018-08-02 210 110 232.5
4 2018-08-02 230 120 247.5
5 2018-08-02 260 150 247.5
6 2018-08-03 200 115 220.0
答案 1 :(得分:0)
我不确定您的预期输出是多少,但是如果您要查找具有多个事务的日期的最接近大小的平均值,则可以执行以下操作。如果您正在寻找其他东西,请提供预期的输出:
$"/{tenant}/chatHub"