Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一次计算两个值的GroupBy聚合函数_Python_Pandas_Pandas Groupby_Aggregate - Fatal编程技术网

Python 一次计算两个值的GroupBy聚合函数

Python 一次计算两个值的GroupBy聚合函数,python,pandas,pandas-groupby,aggregate,Python,Pandas,Pandas Groupby,Aggregate,我有一个类似于以下的datafame: import pandas as pd df = pd.DataFrame({ 'A': [1, 1, 1, 2, 2, 2], 'B': [1, 2, 3, 4, 5, 6], 'C': [4, 5, 6, 7, 8, 9], }) expected = df.groupby('A').agg([min, max]) # B C # min max min max # A

我有一个类似于以下的datafame:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 1, 1, 2, 2, 2],
    'B': [1, 2, 3, 4, 5, 6],
    'C': [4, 5, 6, 7, 8, 9],
})
expected = df.groupby('A').agg([min, max])

#     B       C    
#   min max min max
# A                
# 1   1   3   4   6
# 2   4   6   7   9
现在我想对每个组生成两个值进行分组和聚合。结果应与以下类似:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 1, 1, 2, 2, 2],
    'B': [1, 2, 3, 4, 5, 6],
    'C': [4, 5, 6, 7, 8, 9],
})
expected = df.groupby('A').agg([min, max])

#     B       C    
#   min max min max
# A                
# 1   1   3   4   6
# 2   4   6   7   9
但是,在我的例子中,我没有使用两个不同的函数
min
max
,而是使用一个函数同时计算这两个值:

def minmax(x):
    """This function promises to compute the min and max in one go."""
    return min(x), max(x)
现在我的问题是,如何使用这个函数为每个组生成两个聚合值

这有点像,但我不知道怎么做。我能想到的最好方法是使用双重嵌套的
apply
,但是这不是很优雅,而且它会在行而不是列上生成多索引:

result = df.groupby('A').apply(
    lambda g: g.drop(columns='A').apply(
        lambda h: pd.Series(dict(zip(['min', 'max'], minmax(h))))
    )
)

#        B  C
# A          
# 1 min  1  4
#   max  3  6
# 2 min  4  7
#   max  6  9
另一个解决方案:

pd.concat({k:d.agg(minmax).set_axis(['min','max'])
           for k,d in df.drop('A',axis=1).groupby(df['A'])
          })
输出:

       B  C
1 min  1  4
  max  3  6
2 min  4  7
  max  6  9
另一个解决方案:

pd.concat({k:d.agg(minmax).set_axis(['min','max'])
           for k,d in df.drop('A',axis=1).groupby(df['A'])
          })
输出:

       B  C
1 min  1  4
  max  3  6
2 min  4  7
  max  6  9

如果您一直使用返回值的
元组的函数。我想:

  • 定义一个新函数,将
    元组
    值包装到
    dict
    中,以便预定义
    dict.keys()
    以与您希望的列名对齐
  • 循环使用谨慎的
    ,不要浪费时间和空间
    
    包裹函数 小心
    进行
    循环
    我的目标是将此字典传递到
    pd.DataFrame
    构造函数中。这意味着,我希望键中的
    多索引
    列元素的元组。我希望值是字典,键是索引元素

    dat = {}
    for a, d in df.set_index('A').groupby('A'):
        for cn, c in d.iteritems():
            for k, v in minmax_dict(c).items():
                dat.setdefault((cn, k), {})[a] = v
    
    pd.DataFrame(dat).rename_axis('A')
    
        B       C    
      min max min max
    A                
    1   1   3   4   6
    2   4   6   7   9
    

    补充细节 看看这本特制的词典

    data
    
    {('B', 'min'): {1: 1, 2: 4},
     ('B', 'max'): {1: 3, 2: 6},
     ('C', 'min'): {1: 4, 2: 7},
     ('C', 'max'): {1: 6, 2: 9}}
    

    如果您一直使用返回值的
    元组的函数。我想:

  • 定义一个新函数,将
    元组
    值包装到
    dict
    中,以便预定义
    dict.keys()
    以与您希望的列名对齐
  • 循环使用谨慎的
    ,不要浪费时间和空间
    
    包裹函数 小心
    进行
    循环
    我的目标是将此字典传递到
    pd.DataFrame
    构造函数中。这意味着,我希望键中的
    多索引
    列元素的元组。我希望值是字典,键是索引元素

    dat = {}
    for a, d in df.set_index('A').groupby('A'):
        for cn, c in d.iteritems():
            for k, v in minmax_dict(c).items():
                dat.setdefault((cn, k), {})[a] = v
    
    pd.DataFrame(dat).rename_axis('A')
    
        B       C    
      min max min max
    A                
    1   1   3   4   6
    2   4   6   7   9
    

    补充细节 看看这本特制的词典

    data
    
    {('B', 'min'): {1: 1, 2: 4},
     ('B', 'max'): {1: 3, 2: 6},
     ('C', 'min'): {1: 4, 2: 7},
     ('C', 'max'): {1: 6, 2: 9}}
    

    解决方案应等同于df.groupby('A').agg([min,max])
    ,即多索引应位于列上。此外,在组上循环与在groupby对象上使用
    apply
    没有太大区别,是吗?使用unstack链接解决方案,您应该获得所需的格式。是的,它等同于应用。最后一个建议和@piRSqaured一样,避免使用minmax函数使用
    unstack
    提供了一个几乎相同的解决方案,唯一的区别是未命名的索引。我的问题中使用的示例可能有点误导,因为它由两个不同的函数组成。在我的用例中,我有一个函数
    myfunc
    ,它不能简单地分成两个函数。唯一的方法是
    df.groupby('A').agg([lambda x:myfunc(x)[0],lambda x:myfunc(x)[1]])
    ,但是
    myfunc
    的计算成本不低,因此这会浪费大量的计算能力。如果需要名称,请在取消堆栈后将其与
    rename_axis('A')
    链接。好的,这正是我来这里问这个问题的原因,因为堆叠和嵌套这么多函数调用已经不再是真正可读的了。所以我希望有一个更干净的解决方案。无论如何,谢谢你的回答。顺便说一下,您应该更新它以匹配问题的预期结果。解决方案应该相当于
    df.groupby('A').agg([min,max])
    ,即多索引应该位于列上。此外,在组上循环与在groupby对象上使用
    apply
    没有太大区别,是吗?使用unstack链接解决方案,您应该获得所需的格式。是的,它等同于应用。最后一个建议和@piRSqaured一样,避免使用minmax函数使用
    unstack
    提供了一个几乎相同的解决方案,唯一的区别是未命名的索引。我的问题中使用的示例可能有点误导,因为它由两个不同的函数组成。在我的用例中,我有一个函数
    myfunc
    ,它不能简单地分成两个函数。唯一的方法是
    df.groupby('A').agg([lambda x:myfunc(x)[0],lambda x:myfunc(x)[1]])
    ,但是
    myfunc
    的计算成本不低,因此这会浪费大量的计算能力。如果需要名称,请在取消堆栈后将其与
    rename_axis('A')
    链接。好的,这正是我来这里问这个问题的原因,因为堆叠和嵌套这么多函数调用已经不再是真正可读的了。所以我希望有一个更干净的解决方案。无论如何,谢谢你的回答。顺便问一下,你应该更新它以匹配问题的预期结果。通过“不要那样做”,你指的是你的答案还是我的目标?我还应该注意到,解决方案应该比简单的
    df.groupby('A').agg([lambda x:minmax(x)[0],lambda x:minmax(x)[1]])更有效。
    。当然,为了对此进行基准测试,我需要提供一个更复杂的数据帧以及一个更有用的
    minmax
    实现。当您建议我不应该这样做时,可能会有误解,因为我没有太多选择。为了简化示例,我使用了
    minmax
    函数,但实际上我有一个函数不能简单地拆分为多个其他函数。事实上,我的函数将每组的数据拟合到一个模型中,然后返回一组拟合参数及其误差估计值(因此实际上不止两个)。生成的数据框应该包含每个组的参数估计值。啊,那就是mak