【问题标题】:Pandas: ValueError when pivoting dataframe with MultiIndexPandas:使用 MultiIndex 旋转数据框时出现 ValueError
【发布时间】:2017-11-25 17:05:02
【问题描述】:

我有以下代码,其目的是对从 Oracle 数据库检索到的 SQL 表进行透视:

s = "SELECT Country || '_' || Product || '_' || Flow Ref, " + \
        "Country, Product, Flow, zm, Qty " + \
    "FROM Volumes "

#Following will simply pull from db into a dataframe 
df = fb.QueryDB(s)

#Put ZM as column headers
df = df.pivot(values = 'QTY', index = 'REF', columns = 'ZM')

#Format the column headers
df.columns = [x.strftime('%b-%Y') for x in df.columns]

一切都很好,我得到一个数据框,例如:

         Mar-2017    Apr-2017
 Ref
A_B_C      100          110
D_E_F      500          210
G_H_I      310          150

除了现在我想创建一个多索引,如下:

                                    Mar-2017    Apr-2017
 Ref    Country   Product   Flow
A_B_C     A          B       C        100          110
D_E_F     D          E       F        500          210
G_H_I     G          H       I        310          150    

为此,我编辑了将数据框旋转到的行:

df = df.pivot(values = 'QTY', index = ['REF','COUNTRY','PRODUCT','FLOW'], columns = 'ZM')

这会产生以下错误

ValueError: 传递的项目数错误 1859796,位置暗示 4

非常感谢您的帮助。

【问题讨论】:

    标签: python pandas dataframe pivot


    【解决方案1】:

    首先尝试set_index + unstack

    data = {'REF' : ['A_B_C','D_E_F','G_H_I','A_B_C','D_E_F','G_H_I'],
            'COUNTRY' : list('ADGADG'),
            'PRODUCT' : list('BEHBEH'),
            'FLOW' : list('CFICFI'),
             'QTY':[100,500,310,110,210,150],
             'ZM':pd.to_datetime(['2017-03-01'] * 3 + ['2017-04-01'] * 3 )}
    df = pd.DataFrame(data)
    print (df)
      COUNTRY FLOW PRODUCT  QTY    REF         ZM
    0       A    C       B  100  A_B_C 2017-03-01
    1       D    F       E  500  D_E_F 2017-03-01
    2       G    I       H  310  G_H_I 2017-03-01
    3       A    C       B  110  A_B_C 2017-04-01
    4       D    F       E  210  D_E_F 2017-04-01
    5       G    I       H  150  G_H_I 2017-04-01
    
    df = df.set_index(['REF','COUNTRY','PRODUCT','FLOW', 'ZM'])['QTY']
           .unstack()
           .rename_axis(None, axis=1)
    df.columns = df.columns.strftime('%b-%Y')
    print (df)
                                Mar-2017  Apr-2017
    REF   COUNTRY PRODUCT FLOW                    
    A_B_C A       B       C          100       110
    D_E_F D       E       F          500       210
    G_H_I G       H       I          310       150
    

    如果返回错误:

    ValueError:索引包含重复条目,无法重塑

    需要 pivot_table 和一些聚合函数,如果重复则适用:

    data = {'REF' : ['A_B_C','A_B_C','G_H_I','A_B_C','D_E_F','G_H_I'],
            'COUNTRY' : list('AAGADG'),
            'PRODUCT' : list('BBHBEH'),
            'FLOW' : list('CCICFI'),
             'QTY':[100,500,310,110,210,150],
             'ZM':pd.to_datetime(['2017-03-01'] * 3 + ['2017-04-01'] * 3 )}
    df = pd.DataFrame(data)
    print (df)
      COUNTRY FLOW PRODUCT  QTY    REF         ZM
    0       A    C       B  100  A_B_C 2017-03-01 <-dupe COUNTRY,FLOW,PRODUCT,QTY,REF 
    1       A    C       B  500  A_B_C 2017-03-01 <-dupe COUNTRY,FLOW,PRODUCT,QTY,REF 
    2       G    I       H  310  G_H_I 2017-03-01
    3       A    C       B  110  A_B_C 2017-04-01
    4       D    F       E  210  D_E_F 2017-04-01
    5       G    I       H  150  G_H_I 2017-04-01
    
    
    df = df.pivot_table(values = 'QTY', 
                        index = ['REF','COUNTRY','PRODUCT','FLOW'], 
                        columns = 'ZM', 
                        aggfunc='mean')
    
    df.columns = df.columns.strftime('%b-%Y')
    print (df)
                                Mar-2017  Apr-2017
    REF   COUNTRY PRODUCT FLOW                    
    A_B_C A       B       C        300.0     110.0
    D_E_F D       E       F          NaN     210.0
    G_H_I G       H       I        310.0     150.0
    

    或者groupby + aggregate function + unstack

    df = df.groupby(['REF','COUNTRY','PRODUCT','FLOW', 'ZM'])['QTY'].mean().unstack()
    df.columns = df.columns.strftime('%b-%Y')
    print (df)
                                Mar-2017  Apr-2017
    REF   COUNTRY PRODUCT FLOW                    
    A_B_C A       B       C        300.0     110.0
    D_E_F D       E       F          NaN     210.0
    G_H_I G       H       I        310.0     150.0
    

    【讨论】:

    • 选项 #1 有效。选项 #2 创建了一个 ValueError: Index contains duplicate entries, cannot reshape
    • 是的,pivot_table 都有效,但我应该指出我上面有一个错误,所以我需要在你的代码中用 FLOW 替换 ZM。谢谢。
    • 超级,我编辑它。 df.set_index(['REF','COUNTRY','PRODUCT','FLOW', 'ZM'])['QTY'].unstack() 也有效?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2022-12-04
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2021-02-06
    相关资源
    最近更新 更多