熊猫数据框在没有for循环的情况下遍历行

时间:2018-08-05 21:02:39

标签: python pandas dataframe

我有一个约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。

2 个答案:

答案 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_asofdate使用nearest sizesort_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"