代码之家  ›  专栏  ›  技术社区  ›  Adam Hughes

在没有透视表的情况下展平pandas数据帧

  •  2
  • Adam Hughes  · 技术社区  · 8 年前

    groupby ,需要以某种方式将其展平 similar to flattening a pivot table 。大多数分析都是围绕分组对象构建的,因此不必重构到数据透视表中。

    dummy_data = pd.DataFrame({'Ccy' : ['EUR', 'EUR', 'CAD', 'CAD', 'EUR', 'EUR', 'CAD', 'EUR'],
                      'Venue' : ['BAML']*5 + ['BARX']*3,
                      'Price': np.abs(np.random.randn(8)),
                      'volume': np.abs(10*np.random.randn(8))
                       }, 
                      index = pd.date_range('7/19/2017', periods=8))
    
    dummy_data.index.name = "datetime"
    print dummy_data
    
    
    >>>            Ccy     Price Venue     volume
    datetime                                  
    2017-07-19  EUR  1.338521  BAML  11.227553
    2017-07-20  EUR  0.882715  BAML   0.307711
    2017-07-21  CAD  0.977815  BAML  14.196170
    2017-07-22  CAD  1.262272  BAML   0.055213
    2017-07-23  EUR  0.752433  BAML   5.315777
    2017-07-24  EUR  0.699008  BARX   2.299045
    2017-07-25  CAD  1.625567  BARX   6.474822
    2017-07-26  EUR  2.122562  BARX   5.026135
    

    目标是按 Ccy Venue ,应用 filter 操作到每个子组,然后将这些组展平回原始帧的格式。考虑一个简单的过滤器,其中保留行 price > 0.8

    dummy_data.groupby(['Ccy', 'Venue']).apply(lambda x: x[x['Price'] > 0.8])
    
    >>>                      Ccy     Price Venue     volume
    Ccy Venue datetime                                  
    CAD BAML  2017-07-21  CAD  0.977815  BAML  14.196170
              2017-07-22  CAD  1.262272  BAML   0.055213
        BARX  2017-07-25  CAD  1.625567  BARX   6.474822
    EUR BAML  2017-07-19  EUR  1.338521  BAML  11.227553
              2017-07-20  EUR  0.882715  BAML   0.307711
        BARX  2017-07-26  EUR  2.122562  BARX   5.026135
    

    地点

    Ccy Venue datetime                                  
    CAD BAML  2017-07-21  ...                       CAD BAML 2017-07-21  ...
              2017-07-22  ...                       CAD BAML 2017-07-22  ... 
        BARX  2017-07-25  ...    ---> BECOMES --->  CAD BARX 2017-07-25 ...
    EUR BAML  2017-07-19  ...                       EUR BAML 2017-07-19 ... 
              2017-07-20  ...                       EUR BAML 2017-07-20  ...
    

    我需要这样做,因为我们有一系列绘图实用程序,它们不够灵活,无法处理分组数据 .难道不应该有一个 ungroup() flatten() 方法,该方法与 groupby() 活动

    本例中的平凡过滤器可以应用于未分组的数据。实际上,我的过滤器更复杂,只在子组上有意义。


    (尝试1和2从 pivot table solution )

    : melt 方法丢失 datetime

        print dummy_data.groupby(['Ccy', 'Venue']).apply(lambda x: x[x['Price'] > 0.8]).melt()
    
    >>>   variable      value
    0       Ccy        CAD
    1       Ccy        CAD
    2       Ccy        CAD
    3       Ccy        EUR
    4       Ccy        EUR
    5       Ccy        EUR
    6     Price   0.977815
    7     Price    1.26227
    8     Price    1.62557
    9     Price    1.33852
    

    尝试2: 这个 accepted answer 导致 KeyError

    dummy_data.groupby(['Ccy', 'Venue']).apply(lambda x: x[x['Price'] > 0.8]).unstack().reset_index().drop('level_0', axis=1)
    

    reset_index() 导致ValueError

    dummy_data.groupby(['Ccy', 'Venue']).apply(lambda x: x[x['Price'] > 0.8]).reset_index()
    

    as_index=False (无 group_keys 关键字)

    out = dummy_data.groupby(['Ccy', 'Venue'], as_index=False).apply(lambda x: x[x['Price'] > 0.8])
    print out
    print out.index
    
                  Ccy     Price Venue     volume
      datetime                                  
    0 2017-07-21  CAD  0.977815  BAML  14.196170
      2017-07-22  CAD  1.262272  BAML   0.055213
    1 2017-07-25  CAD  1.625567  BARX   6.474822
    2 2017-07-19  EUR  1.338521  BAML  11.227553
      2017-07-20  EUR  0.882715  BAML   0.307711
    3 2017-07-26  EUR  2.122562  BARX   5.026135
    MultiIndex(levels=[[0, 1, 2, 3], [2017-07-19 00:00:00, 2017-07-20 00:00:00, 2017-07-21 00:00:00, 2017-07-22 00:00:00, 2017-07-25 00:00:00, 2017-07-26 00:00:00]],
               labels=[[0, 0, 1, 2, 2, 3], [2, 3, 4, 0, 1, 5]],
               names=[None, u'datetime'])
    

    这让我非常接近,但这个物体仍然是 MultiIndexed

    1 回复  |  直到 8 年前
        1
  •  2
  •   cs95 abhishek58g    8 年前

    这可能是您想要的:

    dummy_data.groupby(['Ccy', 'Venue'], group_keys=False)\
              .apply(lambda x: x[x['Price'] > 0.8])
    
    推荐文章