1

我可以使用 pandas 中的 pivot_table 来实现我想要的输出(如下所示)或与以下数据集类似的东西吗?我正在尝试做类似的事情:

pivot_table(df, rows=['region'], cols=['area','distributor','salesrep'], 
            aggfunc=np.sum, margins=True).stack(['area','distributor','salesrep'])

但我只得到每个区域的小计,如果我将区域从 cols 移动到行,那么我只会得到每个区域的小计。

数据集:

region 区域经销商 salesrep sales invoice_count
北海中部 HIN 营销 TLS 500 25
北海中部 HIN 营销 TLS 500 25
北海中部 HIN MARKETING OSE 500 25
北海中部 HIN MARKETING OSE 500 25
北海中环广恒 TCS 500 25
北海中环广恒 TCS 500 25
北海中环广兴 LBH 500 25
北海中环广兴 LBH 500 25
怡保中央 SGH EDERAN CHAN 500 25
怡保中央 SGH EDERAN CHAN 500 25
怡保中央 SGH EDERAN KAMACHI 500 25
怡保中央 SGH EDERAN KAMACHI 500 25
怡保中部 CORE SYN LILIAN 500 25
怡保中部 CORE SYN LILIAN 500 25
怡保中部 CORE SYN TEOH 500 25
怡保中部 CORE SYN TEOH 500 25
东 JB 利华 NF05 500 25
东 JB 利华 NF05 500 25
东 JB 丽华 NF06 500 25
东 JB 丽华 NF06 500 25
东 JB WONDER F&B SEREN 500 25
东 JB WONDER F&B SEREN 500 25
东 JB WONDER F&B MONC 500 25
东 JB WONDER F&B MONC 500 25
东 PJ PENGEDAR NORM 500 25
东 PJ PENGEDAR NORM 500 25
东 PJ PENGEDAR SIMON 500 25
东 PJ PENGEDAR SIMON 500 25
东 PJ HEBAT OGI 500 25
东 PJ HEBAT OGI 500 25
东 PJ HEBAT MIGI 500 25
东 PJ HEBAT MIGI 500 25

期望的输出:

region 地区经销商 salesrep invoice_count sales
总计 800 16000
中环 中环 总计 400 8000
北海中部 北海 总计 200 4000
北海中部 HIN MARKETING HIN MARKETING 总计 100 2000
Central Butterworth HIN MARKETING OSE 50 1000
北海中部 HIN 营销 TLS 50 1000
北海中环 KWANG HENG KWANG HENG Total 100 2000
北海中环广兴 LBH 50 1000
北海中环广亨 TCS 50 1000
怡保中环 怡保 总计 200 4000
怡保中环 CORE SYN CORE SYN 总计 100 2000
Central Ipoh CORE SYN LILIAN 50 1000
怡保中部 CORE SYN TEOH 50 1000
怡保中央 SGH EDERAN SGH EDERAN 总计 100 2000
怡保中央 SGH EDERAN CHAN 50 1000
Central Ipoh SGH EDERAN KAMACHI 50 1000
东东 总计 400 8000
东新山新山总计 200 4000
East JB LEI WAH LEI WAH 合计 100 2000
东 JB 利华 NF05 50 1000
东 JB 利华 NF06 50 1000
East JB WONDER F&B WONDER F&B Total 100 2000
东 JB WONDER F&B MONC 50 1000
东 JB WONDER F&B SEREN 50 1000
东 PJ PJ 总计 200 4000
东 PJ HEBAT HEBAT 总计 100 2000
东 PJ HEBAT MIGI 50 1000
东 PJ HEBAT OGI 50 1000
东 PJ PENGEDAR PENDEGAR 总计 100 2000
东 PJ PENGEDAR NORM 50 1000
东 PJ PENGEDAR SIMON 50 1000
4

2 回答 2

1

我们可以使用groupby而不是pivot_table

import numpy as np
import pandas as pd


def label(ser):
    return '{s} Total'.format(s=ser)

filename = 'data.txt'
df = pd.read_table(filename, delimiter='\t')

total = pd.DataFrame({'region': ['Grand Total'],
                      'invoice_count': df['invoice_count'].sum(),
                      'sales': df['sales'].sum()})
total['total_rank'] = 1

region_total = df.groupby(['region'], as_index=False).sum()
region_total['area'] = region_total['region'].apply(label)
region_total['region_rank'] = 1

area_total = df.groupby(['region', 'area'], as_index=False).sum()
area_total['distributor'] = area_total['area'].apply(label)
area_total['area_rank'] = 1

dist_total = df.groupby(
    ['region', 'area', 'distributor'], as_index=False).sum()
dist_total['salesrep'] = dist_total['distributor'].apply(label)

rep_total = df.groupby(
    ['region', 'area', 'distributor', 'salesrep'], as_index=False).sum()

# UNION the DataFrames into one DataFrame
result = pd.concat([total, region_total, area_total, dist_total, rep_total])

# Replace NaNs with empty strings
result.fillna({'region': '', 'area': '', 'distributor': '', 'salesrep':
              ''}, inplace=True)

# Reorder the rows
sorter = np.lexsort((
    result['distributor'].rank(),
    result['area_rank'].rank(),
    result['area'].rank(),
    result['region_rank'].rank(),
    result['region'].rank(),
    result['total_rank'].rank()))
result = result.take(sorter)
result = result.reindex(
    columns=['region', 'area', 'distributor', 'salesrep', 'invoice_count', 'sales'])
print(result.to_string(index=False))

产量

      region           area        distributor             salesrep  invoice_count  sales
 Grand Total                                                                   800  16000
     Central  Central Total                                                    400   8000
     Central    Butterworth  Butterworth Total                                 200   4000
     Central    Butterworth      HIN MARKETING  HIN MARKETING Total            100   2000
     Central    Butterworth      HIN MARKETING                  OSE             50   1000
     Central    Butterworth      HIN MARKETING                  TLS             50   1000
     Central    Butterworth         KWANG HENG     KWANG HENG Total            100   2000
     Central    Butterworth         KWANG HENG                  LBH             50   1000
     Central    Butterworth         KWANG HENG                  TCS             50   1000
     Central           Ipoh         Ipoh Total                                 200   4000
     Central           Ipoh           CORE SYN       CORE SYN Total            100   2000
     Central           Ipoh           CORE SYN               LILIAN             50   1000
     Central           Ipoh           CORE SYN                 TEOH             50   1000
     Central           Ipoh         SGH EDERAN     SGH EDERAN Total            100   2000
     Central           Ipoh         SGH EDERAN                 CHAN             50   1000
     Central           Ipoh         SGH EDERAN              KAMACHI             50   1000
        East     East Total                                                    400   8000
        East             JB           JB Total                                 200   4000
        East             JB            LEI WAH        LEI WAH Total            100   2000
        East             JB            LEI WAH                 NF05             50   1000
        East             JB            LEI WAH                 NF06             50   1000
        East             JB         WONDER F&B     WONDER F&B Total            100   2000
        East             JB         WONDER F&B                 MONC             50   1000
        East             JB         WONDER F&B                SEREN             50   1000
        East             PJ           PJ Total                                 200   4000
        East             PJ              HEBAT          HEBAT Total            100   2000
        East             PJ              HEBAT                 MIGI             50   1000
        East             PJ              HEBAT                  OGI             50   1000
        East             PJ           PENGEDAR       PENGEDAR Total            100   2000
        East             PJ           PENGEDAR                 NORM             50   1000
        East             PJ           PENGEDAR                SIMON             50   1000
于 2013-04-14T18:41:16.130 回答
0

我不知道如何在表格中获取小计,但如果你运行

df.pivot_table(rows=['region','area','distributor','salesrep'],
  aggfunc=np.sum, margins=True)

你会得到

                                            invoice_count  sales
region  area        distributor   salesrep                      
Central Butterworth HIN MARKETING OSE                  50   1000
                                  TLS                  50   1000
                    KWANG HENG    LBH                  50   1000
                    KWANG HENGG   TCS                  50   1000
        Ipoh        CORE SYN      LILIAN               50   1000
                                  TEOH                 50   1000
                    SGH EDERAN    CHAN                 50   1000
                                  KAMACHI              50   1000
East    JB          LEI WAH       NF05                 50   1000
                                  NF06                 50   1000
                    WONDER F&B    MONC                 50   1000
                                  SEREN                50   1000
        PJ          HEBAT         MIGI                 50   1000
                                  OGI                  50   1000
                    PENGEDAR      NORM                 50   1000
                                  SIMON                50   1000
All                                                   800  16000

如果您想要基于 sayregion和的总数area,您可以运行

df.pivot_table(rows=['region', 'area'], aggfunc=np.sum, margins=True)

这导致

                     invoice_count  sales
region  area                             
Central Butterworth            200   4000
        Ipoh                   200   4000
East    JB                     200   4000
        PJ                     200   4000
All                            800  16000
于 2013-04-14T11:15:58.287 回答