特定股票每日的绝对变化总和

时间:2017-02-28 21:05:46

标签: python pandas group-by

我有一个数据框,每个日期我想计算每个日期每个股票的销售绝对变化总和。

示例df:

            Stock      Sales    Data 1
1/1/2012    Amazon    120       0.996691907
1/1/2012    Apple     230       0.084699221
1/1/2012    Microsoft 340       0.141253424
1/1/2012    Google    230       0.506264018
1/2/2012    Amazon    340       0.646633737
1/2/2012    Apple     1250      0.204030887
1/2/2012    Microsoft 850       0.556935133
1/2/2012    Dell      650       0.771751177
1/2/2012    Yahoo     650       0.615222763
1/2/2012    Verizon   1065      0.504410742
1/2/2012    Vodafone  200       0.752335341
1/2/2012    Blackberry 1465     0.693017964
1/2/2012    AT&T      2000      0.262392424
1/3/2012    Apple     1465      0.851841806
1/3/2012    Amazon    1465      0.70635569
1/3/2012    AT&T      700       0.911297224
1/3/2012    Blackberry 235      0.118843588
1/3/2012    Vodafone  500       0.07255267

输出df_new将是:

1/1/2012    920
1/2/2012    7780
1/3/2012    11050

计算:

对于 1/1/2012 (索引中的第一个日期),计算将只是当天销售额的总和(120 + 230 + 340 + 230)= 920

对于 1/2/2012 (下一个日期),计算将是日期变更期间特定股票的销售额的绝对变化。 例如,亚马逊,苹果和微软已经处于第一个日期,其余的股票都是新的,所以绝对变化的总和将是: (abs(340-120)+ abs(1250-230)+ abs(850-340)+ abs(650-0)+ abs(650-0)+ abs(1065-0)+ abs(200-0)+ abs(1465-0)+ abs(2000-0))= 7780。 由于戴尔,雅虎,Verizon,Vodafone,Blackberry,AT& T都是新的,并且在计算前一天不是简单的销售额减去0(因为他们前一天不在那里测量绝对变化)。

1/3/2012 (下一个日期)。计算如下: abs(1465-1250)+ abs(1465-340)+ abs(700-2000)+ abs(235-1465)+ abs(500-20)+ abs(0-1065)+ abs(0-650)+ abs (0-650)-abs(0-850)= 11050 由于微软,戴尔,雅虎和Verizon都是前一个日期而不是当前日期,因此它们的销量为0。

数据集很大,我试图找到一个可以完成所有这些操作的简单代码。数据涉及可能发生剧烈变化的股票,并且可能存在从一个日期到另一个日期没有股票的情况。

2 个答案:

答案 0 :(得分:1)

在熊猫中你可以这样做:

>>> df
           Stock      Sales   Data
1/1/2012   Amazon     120     0.996692
1/1/2012   Apple      230     0.084699
1/1/2012   Microsoft  340     0.141253
1/1/2012   Google     230     0.506264
...
>>> df2 = df.pivot(columns='Stock', values='Sales').fillna(0)
>>> df2
Stock       AT&T  Amazon   Apple  Blackberry   Dell  Google  Microsoft  Verizon  Vodafone  Yahoo
1/1/2012     0.0   120.0   230.0         0.0    0.0   230.0      340.0       0.0       0.0    0.0  
1/2/2012  2000.0   340.0  1250.0      1465.0  650.0     0.0      850.0    1065.0     200.0  650.0  
1/3/2012   700.0  1465.0  1465.0       235.0    0.0     0.0        0.0       0.0     500.0    0.0  
>>> df3 = df2.diff().fillna(df2).abs()
>>> df3
Stock       AT&T  Amazon   Apple  Blackberry   Dell  Google  Microsoft  Verizon  Vodafone  Yahoo  
1/1/2012     0.0   120.0   230.0         0.0    0.0   230.0      340.0       0.0       0.0    0.0  
1/2/2012  2000.0   220.0  1020.0      1465.0  650.0   230.0      510.0    1065.0     200.0  650.0  
1/3/2012  1300.0  1125.0   215.0      1230.0  650.0     0.0      850.0    1065.0     300.0  650.0  
>>> df3.sum(axis=1)
1/1/2012     920.0
1/2/2012    8010.0
1/3/2012    7385.0
dtype: float64

注意:由于OP的计算错误,我得不到同样的结果 -  谷歌似乎从1/2中失踪了,计算只是1/3的错误。

答案 1 :(得分:0)

它更像是伪代码而我没有测试它但它或多或少应该是这样的:

prev_sales = {}
last_sales = {}
last_date = rows[0].date

for row in rows:
    if row.date > last_date:
         res = 0

         for key, value in last_sales.iteritems():
            res += abs(value - prev_sales.get(key, 0))

         print last_date, res

         last_date = row.date
         prev_sales = last_sales
         last_sales = {}

    last_sales[row.stock] += last_sales.get(row.stock, 0)

时间复杂度是O(行数+天数*不同公司的数量),如果大多数公司每天都出现O(行数)。