按组缩小熊猫数据框

时间:2018-06-21 19:34:41

标签: python pandas group-by

我一直在广泛搜索,但是无法解决这个问题:

我在熊猫中有一个数据框,如下所示:

date    ticker Name NoShares SharePrice Volume Relation
2/1/10  aaa    zzz  1        1          1      d 
2/1/10  aaa    yyy  1        2          5      o
2/1/10  aaa    zzz  2        5          2      d  
2/5/10  bbb    xxx  5        5          1      do
2/5/10  ccc    www  5        5          1      d
2/5/10  ccc    www  5        5          1      d
2/5/10  ddd    vvv  5        5          1      o
2/6/10  aaa    zzz  1        1          3      d

要求

  1. 我要按日期和名称分组,并且:
  2. 已汇总了股份数量
  3. 具有一个加权平均股价列(权重为NoShares)
  4. 平均音量并将其作为一列
  5. 保持关系不变

所以我的输出看起来像这样:

date    ticker Name NoShares SharePrice Volume Relation
2/1/10  aaa    zzz  3        3.6        1      d 
2/1/10  aaa    yyy  1        2          5      o
2/5/10  bbb    xxx  5        5          1      do
2/5/10  ccc    www  10       5          1      d
2/5/10  ddd    vvv  5        5          1      o
2/6/10  aaa    zzz  1        1          3      d

我在堆栈溢出时尝试了文档和其他答案,但似乎无法正确处理。感谢帮助。干杯。

2 个答案:

答案 0 :(得分:1)

这是我的解决方案:

grpby = df.groupby(['date','Name'])
a = grpby.apply(lambda x: np.average(a = x['SharePrice'],weights=x['NoShares'])).to_frame(name='SharePrice')
b = grpby.agg({'NoShares':'sum','Volume':'mean','Relation':'max'})
print b.join(a)

             Volume Relation  NoShares  SharePrice
date   Name                                       
2/1/10 yyy   5.0000        o         1      2.0000
       zzz   1.5000        d         3      3.6667
2/5/10 vvv   1.0000        o         5      5.0000
       www   1.0000        d        10      5.0000
       xxx   1.0000       do         5      5.0000
2/6/10 zzz   3.0000        d         1      1.0000

之后只需要reset_index()。

答案 1 :(得分:0)

我在这里做了一个假设。当您说出按日期和姓名分组并保持联系时,我假设这些股票的联系方式和联系也将是唯一的。因此,为简单起见,我将所有4个分组。

df = pd.DataFrame([
                ['2/1/10', 'aaa', 'zzz', 1, 1, 1, 'd'], 
                ['2/1/10', 'aaa', 'yyy', 1, 2, 5, 'o'],
                ['2/1/10', 'aaa', 'zzz', 2, 5, 2, 'd'],  
                ['2/5/10', 'bbb', 'xxx', 5, 5, 1, 'do'],
                ['2/5/10', 'ccc', 'www', 5, 5, 1, 'd'],
                ['2/5/10', 'ccc', 'www', 5, 5, 1, 'd'],
                ['2/5/10', 'ddd', 'vvv', 5, 5, 1, 'o'],
                ['2/6/10', 'aaa', 'zzz', 1, 1, 3, 'd']],
             columns = ['date', 'ticker', 'Name', 'NoShares',
                        'SharePrice', 'Volume', 'Relation'])

def process_date(dg):
    return pd.DataFrame([[
                        dg['NoShares'].sum(),
                        (dg['NoShares'] * dg['SharePrice']).sum() / dg['NoShares'].sum(),
                        dg['Volume'].mean(),
                        ]], columns=['NoShares', 'SharePrice', 'Volume'])

df.groupby(['date', 'ticker', 'Name', 'Relation']).apply(process_date).reset_index(4, drop=True).reset_index(drop=False)

结果:

     date ticker Name Relation  NoShares  SharePrice  Volume
0  2/1/10    aaa  yyy        o         1    2.000000     5.0
1  2/1/10    aaa  zzz        d         3    3.666667     1.5
2  2/5/10    bbb  xxx       do         5    5.000000     1.0
3  2/5/10    ccc  www        d        10    5.000000     1.0
4  2/5/10    ddd  vvv        o         5    5.000000     1.0
5  2/6/10    aaa  zzz        d         1    1.000000     3.0