Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.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 将小计添加到Pandas Groupby_Python_Pandas_Pandas Groupby - Fatal编程技术网

Python 将小计添加到Pandas Groupby

Python 将小计添加到Pandas Groupby,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我正在寻找一种更干净的方法来向Pandas groupby添加小计 这是我的数据框: df = pd.DataFrame({ 'Category':np.random.choice( ['Group A','Group B'], 50), 'Sub-Category':np.random.choice( ['X','Y'], 50), 'Product':np.random.choice( ['Product 1','Product 2'], 50), 'Units_Sold':np.rando

我正在寻找一种更干净的方法来向Pandas groupby添加小计

这是我的数据框:

df = pd.DataFrame({
'Category':np.random.choice( ['Group A','Group B'], 50),
'Sub-Category':np.random.choice( ['X','Y'], 50),
'Product':np.random.choice( ['Product 1','Product 2'], 50),
'Units_Sold':np.random.randint(1,100, size=(50)),
'Dollars_Sold':np.random.randint(100,1000, size=50),
'Date':np.random.choice( pd.date_range('1/1/2011','03/31/2011',  
                      freq='D'), 50, replace=False)})
在此基础上,我创建了一个新的Groupby数据框架,如下所示:

df1 = df.groupby(['Category','Sub-Category','Product',pd.TimeGrouper(key='Date',freq='M')]).agg({'Units_Sold':'sum','Dollars_Sold':'sum'}).unstack().fillna(0)
我想提供分类和子分类的小计。我可以使用以下代码执行此操作:

df2 = df1.groupby(level=[0,1]).sum()
df2.index = pd.MultiIndex.from_arrays([df2.index.get_level_values(0),
                                   df2.index.get_level_values(1) + ' Total',
                                   len(df2) * ['']])
df3 = df1.groupby(level=[0]).sum()
df3.index = pd.MultiIndex.from_arrays([df3.index.get_level_values(0) + ' Total',
                                   len(df3) * [''],
                                   len(df3) * ['']])
pd.concat([df1,df2,df3]).sort_index()
这给了我想要的数据帧:

我的问题是,有没有比为每一层创建一个新的数据帧然后合并更符合python的方法呢?我对此进行了研究,但找不到更好的方法。我必须为许多不同的多索引数据帧这样做&我正在寻找更好的解决方案

提前感谢您的帮助

使用其他信息编辑:

感谢@Wen和@DaFanat的回复。我试图使用我的数据[link]上提供的@Wen链接:

这是总计,但忽略了构成第二级列的日期。它留给我这个结果


我试图用groupby添加一个TimeGrouper,但返回了一个错误。任何帮助都将不胜感激。谢谢

通过将您的上述尝试与@piRSquared中的示例相结合,我可以让您更接近

列表必须与多索引匹配。请尝试以下方法:

iList = ['Category','Sub-Category','Product']
pd.concat([
    df1.assign(
        **{x: '' for x in iList[i:]}
    ).groupby(iList).sum() for i in range(1,4)
]).sort_index()
它没有在正确的位置显示“总计”一词,也没有在每个组的底部显示总计,但至少在功能上或多或少是正确的。我的总数不匹配,因为数据框中的值是随机的

我花了一段时间才完成中提供的原始答案。但同样的逻辑也适用于此

assign()将列中的值替换为在多索引列列表的元素上执行的dict理解返回的dict中的值。
然后groupby()只为那些未加空格的列查找唯一值,并相应地求和。
这些GroupBy包含在一个列表中,因此pd.concat()只需组合这些行集。
和sort_index()将索引标签按升序排列。
(是的,您仍然会收到关于“列名和索引级别”的警告,但它仍然有效。)


这里有一个。在上面的评论之后-这里是另一个,有许多方法。Yw,你应该感谢PiR:)@Wen谢谢你的链接-非常感谢!我试着以链接中的示例为例,让它与我的数据一起工作&不幸的是,我无法让它工作。我将更新以上内容以显示我的进度。再次感谢!
iList = ['Category','Sub-Category','Product']
pd.concat([
    df1.assign(
        **{x: '' for x in iList[i:]}
    ).groupby(iList).sum() for i in range(1,4)
]).sort_index()