【问题标题】:Select multiple groups from pandas groupby object从 pandas groupby 对象中选择多个组
【发布时间】:2015-10-10 16:39:22
【问题描述】:

我正在试验 pandas 的 groupby 功能,特别是

gb = df.groupby('model')
gb.hist()

由于 gb 有 50 个组,结果非常混乱,我想只探索前 5 个组的结果。

我找到了如何使用groupsget_group (How to access pandas groupby dataframe by key) 选择单个组,但没有找到如何直接选择多个组。 我能做的最好的就是:

groups = dict(list(gb))
subgroup = pd.concat(groups.values()[:4])
subgroup.groupby('model').hist()

有没有更直接的方法?

【问题讨论】:

  • 选择前 n 个组有点含糊,也许您的意思是 如何将前 n 个组加入单个数据帧.. 类似的东西?另外,您想如何选择组?随机,还是根据群体人数等?
  • 现在我只是按顺序选择它们,有点像使用 head() 或 tail() 只是为了了解数据的外观。我认为我的方法已经在单个数据框中加入了第一组,但这也是一个更有效的解决方案
  • 您可以通过调用gp.groups 来获取组,请参阅:pandas.pydata.org/pandas-docs/stable/generated/… 您最好先过滤您的df,所以df_filt = df[df['model'].isin(df['model'].unique()[:5])] 然后gb = df_filt.groupby('model') #rest of code 与之前

标签: python pandas


【解决方案1】:

我不知道如何将.get_group() method 用于多个组。

不过,您可以iterate through groups

这样做还是有点难看,但这里有一个迭代解决方案:

limit = 5
i = 0
for key, group in gd:
    print(key, group)
    i += 1
    if i >= limit:
        break

您也可以使用.get_group() 进行循环,恕我直言,这有点漂亮,但仍然很丑。

for key in list(gd.groups.keys())[:2]:
    print(gd.get_group(key))

【讨论】:

  • 要对多个组使用 .get_group() 方法,您需要传递一个元组,其中包含 key1 的值和 key2 的值​​ ...
【解决方案2】:

先过滤你的df然后执行groupby会更容易:

In [155]:

df = pd.DataFrame({'model':np.random.randint(1,10,100), 'value':np.random.randn(100)})
first_five = df['model'].sort(inplace=False).unique()[:5]
gp = df[df['model'].isin(first_five)].groupby('model')
gp.first()
Out[155]:
          value
model          
1     -0.505677
2      1.217027
3     -0.641583
4      0.778104
5     -1.037858

【讨论】:

    【解决方案3】:

    你可以这样做

    new_gb = pandas.concat( [ gb.get_group(group) for i,group in enumerate( gb.groups) if i < 5 ] ).groupby('model')    
    new_gb.hist()
    

    虽然,我会以不同的方式处理它。您可以使用collections.Counter 对象快速获取群组:

    import collections
    
    df = pandas.DataFrame.from_dict({'model': pandas.np.random.randint(0, 3, 10), 'param1': pandas.np.random.random(10), 'param2':pandas.np.random.random(10)})
    #   model    param1    param2
    #0      2  0.252379  0.985290
    #1      1  0.059338  0.225166
    #2      0  0.187259  0.808899
    #3      2  0.773946  0.696001
    #4      1  0.680231  0.271874
    #5      2  0.054969  0.328743
    #6      0  0.734828  0.273234
    #7      0  0.776684  0.661741
    #8      2  0.098836  0.013047
    #9      1  0.228801  0.827378
    model_groups = collections.Counter(df.model)
    print(model_groups) #Counter({2: 4, 0: 3, 1: 3})
    

    现在您可以像字典一样遍历Counter 对象,并查询您想要的组:

    new_df = pandas.concat( [df.query('model==%d'%key) for key,val in model_groups.items() if val < 4 ] ) # for example, but you can select the models however you like  
    #   model    param1    param2
    #2      0  0.187259  0.808899
    #6      0  0.734828  0.273234
    #7      0  0.776684  0.661741
    #1      1  0.059338  0.225166
    #4      1  0.680231  0.271874
    #9      1  0.228801  0.827378
    

    现在你可以使用内置的pandas.DataFrame.groupby函数

    gb = new_df.groupby('model')
    gb.hist() 
    

    由于model_groups 包含所有组,您可以随意选择。

    注意

    如果您的 model 列包含字符串值(名称或其他内容)而不是整数,则它们的工作方式相同 - 只需将查询参数从 'model==%d'%key 更改为 'model=="%s"'%key

    【讨论】:

      【解决方案4】:
      def get_groups(group_object):
          for i in group_object.groups.keys():
              print(f"____{i}____")
              display(group_object.get_group(i))
      
      
      #get all groups by calling this method 
      
      get_groups( any_group_which_you_made )
      

      【讨论】:

      • 您好,感谢您的回复。发布代码 sn-p 很好,但如果您解释它如何解决 OP 问题,那就更好了。欢迎使用 Stack Overflow。
      【解决方案5】:
      gbidx=list(gb.indices.keys())[:4]
      dfidx=np.sort(np.concatenate([gb.indices[x] for x in gbidx]))
      df.loc[dfidx].groupby('model').hist()
      

      gb.indices 比 gb.groups 或 list(gb) 快

      我相信 concat Index 比 concat DataFrames 更快

      我已经尝试过我的大 csv 文件,该文件有约 416M 行、13 列(包括 str)和 720MB 大小,并且 groupby 超过一个列

      然后将 col 名称更改为问题中的名称

      【讨论】:

        猜你喜欢
        • 2014-06-02
        • 2014-10-30
        • 2023-03-30
        • 2015-11-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-01
        • 1970-01-01
        • 2015-06-21
        相关资源
        最近更新 更多