在pandas数据框中为每个子组添加总行数

时间:2015-11-11 23:47:54

标签: pandas group-by sum row

我有一个数据框,df:

BRAND ART_TYPE  YEAR_MONTH metrics  Value
aaa      xyz      201510       a   4500
aaa      xyz      201510       b   8500
bbc      abc      201510       c   3500
bbc      abc      201510       d  10000
xxx      def      201510       e  15000

我想为每组(['品牌',' ART_TYPE',' YEAR_MONTH'])添加一个总行数 所以结果应该是:

BRAND   ART_TYPE    YEAR_MONTH  metrics Value
aaa     xyz         201510      a       4500
aaa     xyz         201510      b       8500
aaa     xyz         201510      tot     13000
bbc     abc         201510      c       3500
bbc     abc         201510      d       10000
bbc     abc         201510      tot     13500
xxx     def         201510      e       15000
xxx     def         201510      tot     15000

怎么做?我们有什么功能吗?我试过apply和groupby函数,没用。如果需要更多信息,请告诉我。

我试过的代码添加了一列:

df['total'] = df.groupby(['BRAND','ART_TYPE','YEAR_MONTH']).apply(calctot)

def calctot(df):
   return(sum(df['Value']))

这给出了一个错误,即使它有效也会添加一个列。

1 个答案:

答案 0 :(得分:1)

我必须根据推荐的输出更改输入数据帧 我改进了函数calctot - 删除列然后追加sum行。 列level_3是从旧索引创建的,我将其删除。应用函数metrics后,列groupby中的新值为NaN,因此我按值tot填充它们。

#  BRAND ART_TYPE  YEAR_MONTH metrics  Value
#0   aaa      xyz      201510       a   4500
#1   aaa      xyz      201510       b   8500
#2   bbc      abc      201510       c   3500
#3   bbc      abc      201510       d  10000
#4   xxx      def      201510       e  15000


def calctot(df):
    #delete columns
    df = df.drop(['BRAND', 'ART_TYPE', 'YEAR_MONTH'], axis=1)
    #append sum row, ignoring non-numeric column metrics
    return df.append(df.sum(numeric_only=True), ignore_index=True)

#groupby and reset index
df =  df.groupby(['BRAND','ART_TYPE','YEAR_MONTH']).apply(calctot).reset_index()
#delete old index column
df = df.drop(['level_3'], axis=1)
#fill NaN to value tot
df['metrics'] = df['metrics'].fillna('tot')

print df
#  BRAND ART_TYPE  YEAR_MONTH metrics  Value
#0   aaa      xyz      201510       a   4500
#1   aaa      xyz      201510       b   8500
#2   aaa      xyz      201510     tot  13000
#3   bbc      abc      201510       c   3500
#4   bbc      abc      201510       d  10000
#5   bbc      abc      201510     tot  13500
#6   xxx      def      201510       e  15000
#7   xxx      def      201510     tot  15000