【问题标题】:Pandas: transforming the DataFrameGroupBy object to desired formatPandas:将 DataFrameGroupBy 对象转换为所需格式
【发布时间】:2014-02-02 09:52:51
【问题描述】:

我有一个数据框如下:

import pandas as pd
import numpy as np
df = pd.DataFrame({'id' : range(1,9),
                   'code' : ['one', 'one', 'two', 'three',
                             'two', 'three', 'one', 'two'],
                   'colour': ['black', 'white','white','white',
                           'black', 'black', 'white', 'white'],
                   'amount' : np.random.randn(8)},  columns= ['id','code','colour','amount'])

我希望能够通过codecolourids 进行分组,然后根据amount 对它们进行排序。我知道如何groupby()

df.groupby(['code','colour']).head(5)
                id   code colour    amount
code  colour                              
one   black  0   1    one  black -0.117307
      white  1   2    one  white  1.653216
             6   7    one  white  0.817205
three black  5   6  three  black  0.567162
      white  3   4  three  white  0.579074
two   black  4   5    two  black -1.683988
      white  2   3    two  white -0.457722
             7   8    two  white -1.277020

但是,我想要的输出如下,其中我有两列:1.code/colour包含键字符串和 2.id:amount 包含 id - amount 以降序排列的元组 wrt amount

code/colour  id:amount
one/black    {1:-0.117307}
one/white    {2:1.653216, 7:0.817205}
three/black  {6:0.567162}
three/white  {4:0.579074}
two/black    {5:-1.683988}
two/white    {3:-0.457722, 8:-1.277020}

如何将上面显示的DataFrameGroupBy 对象转换为我想要的格式?或者,我不应该首先使用groupby()吗?

编辑: 虽然不是指定的格式,但下面的代码给了我想要的功能:

groups = dict(list(df.groupby(['code','colour'])))
groups['one','white']
   id code colour    amount
1   2  one  white  1.331766
6   7  one  white  0.808739

如何减少组以仅包含 idamount 列?

【问题讨论】:

    标签: python group-by pandas dataframe


    【解决方案1】:

    首先,groupby 代码和颜色,然后应用自定义函数来格式化 id 和数量:

    df = df.groupby(['code', 'colour']).apply(lambda x:x.set_index('id').to_dict('dict')['amount'])
    

    然后修改索引:

    df.index = ['/'.join(i) for i in df.index]
    

    它将返回一个系列,您可以通过以下方式将其转换回DataFrame:

    df = df.reset_index()
    

    最后,添加列名:

    df.columns=['code/colour','id:amount']
    

    结果:

    In [105]: df
    Out[105]: 
       code/colour                               id:amount
    0    one/black                     {1: 0.392264412544}
    1    one/white  {2: 2.13950686015, 7: -0.393002947047}
    2  three/black                      {6: -2.0766612539}
    3  three/white                     {4: -1.18058561325}
    4    two/black                     {5: -1.51959565941}
    5    two/white  {8: -1.7659863039, 3: -0.595666853895}
    

    【讨论】:

    • 谢谢,这似乎很有用。我在网站上搜索并找到了另一个使用dict(list(df.groupby(['code','colour']))) 提供类似功能(尽管不是指定的确切格式)的解决方案。唯一不受欢迎的事情是这不必要地存储了所有列。有没有办法让这个商店只有idamount 列?我将此添加到 EDIT 下的问题中
    • 你做什么功能?字典将代码、颜色对映射到包含 id 和数量的数据框?
    【解决方案2】:

    这是一种“丑陋”的做法。首先,你想要的输出在 Pandas 中不会很好,因为 dict 是不可散列的;所以你可能会失去真正的好处!

    od = OrderedDict()
    for name, group in df.groupby(['code', 'colour']):
        # Convert the group to a dict
        temp = group[['id', 'amount']].sort(['amount'], ascending=[0]).to_dict()
        # Extract id:amount
        temp2 = {temp['id'][key]: temp['amount'][key] for key in temp['amount'].iterkeys()}
        od["%s/%s" % (name)] = temp2
    

    这只是一个开始!不完全符合您的要求。

    【讨论】:

      猜你喜欢
      • 2012-11-14
      • 1970-01-01
      • 2014-01-05
      • 2020-07-07
      • 2017-02-15
      • 1970-01-01
      • 2014-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多