将groupby规则应用于时间序列?

时间:2016-07-23 02:05:28

标签: pandas group-by

我有一个示例DataFrame,如下所示:

    value=DataFrame({'A':[0,-1,0],
                     'B':[1,1,-1],
                     'C':[0,0,1],
                     'D':[-1,1,1]})
    value.index=pd.date_range('1/1/2016',periods=len(value),freq='M')

我希望得到如下答案:

    answer=DataFrame({'A':[0,-1,0],
                      'B':[1,0.5,-0.5],
                      'C':[0,0,-0.5],
                      'D':[-1,0.5,1]})
    answer.index=pd.date_range('1/1/2016',periods=len(value),freq='M')

规则是:

对于每个日期,行的总和为零,并且权重在0-11的每个值类别中平均分配。

例如,

  • 如果有三个-1,一个1,那么答案是-0.33,-0.33,-0.33,1
  • 如果只有一个1和3个-1,那么答案是1,-0.33,-0.33,-0.33
  • 如果有两个1,一个-1,答案是0.5,0.5,-1,0

1 个答案:

答案 0 :(得分:1)

import pandas as pd

value = pd.DataFrame({'A':[0,-1,0],
                 'B':[1,1,-1],
                 'C':[0,0,1],
                 'D':[-1,1,1]})
value.index = pd.date_range('1/1/2016',periods=len(value),freq='M')
pos = (value > 0)
neg = (value < 0)

result = ((value*pos).divide(pos.sum(axis=1), axis=0)
          +(value*neg).divide(neg.sum(axis=1), axis=0))

print(result)

产量

              A    B    C    D
2016-01-31  0.0  1.0  0.0 -1.0
2016-02-29 -1.0  0.5  0.0  0.5
2016-03-31  0.0 -1.0  0.5  0.5

请注意result的最后一行与answer不匹配,但如果我理解正确的话,我认为它与说明相符。

posneg是布尔数据框架。例如,pos为True,其中value为正:

In [206]: pos
Out[206]: 
                A      B      C      D
2016-01-31  False   True  False  False
2016-02-29  False   True  False   True
2016-03-31  False  False   True   True
value*pos为正数时,

valuevalue相同,否则为零

In [207]: value*pos
Out[207]: 
            A  B  C  D
2016-01-31  0  1  0  0
2016-02-29  0  1  0  1
2016-03-31  0  0  1  1

pos.sum(axis=1)计算每行中True个值的数量。将(value*pos)除以计数会产生所需的权重:

In [208]: (value*pos).divide(pos.sum(axis=1), axis=0)
Out[208]: 
              A    B    C    D
2016-01-31  0.0  1.0  0.0  0.0
2016-02-29  0.0  0.5  0.0  0.5
2016-03-31  0.0  0.0  0.5  0.5

对负值也可以这样做。将正面和负面部分加在一起会产生所需的结果。