groupby python TypeError:unorderable类型:tuple()< STR()

时间:2016-08-20 08:49:38

标签: python-3.x pandas

我最初在python 2.7中编写了一些代码,但现在我切换到了python 3.5。 我希望聚合来自几列的数值数据,并按其余列或至少一列进行分组。

这是我的初始数据框“testdf”:

testdf
     PROD_TAG   BRAND   Market         ('VAL', 'Per1')  ('VAL', 'Per2')
        P_1       A     Modern Trade         4.3           0.155
        P_2       A     Traditional Trade    5.7           0
        P_3       B     Modern Trade         10.0          11.2
        P_3       B     Traditional Trade    8.7           6.3
        P_4       C     Modern Trade         12.1          12.3
        P_5       D     Modern Trade         8.0           7.0

最后两个列标题是元组(感谢上尉显而易见)。 Per1和Per2代表各自的时期。

我想执行一行代码,以前在python 2.7上运行:

testdf=testdf.groupby(['BRAND'])[('VAL','P1'),('VAL','P2')].sum()

由于列标题的元组类型和引发,它不起作用:

TypeError: unorderable types: tuple() < str()

现在,如果我像这样重命名列标题:

testdf.columns=['PROD_TAG', 'BRAND', 'Market', 'VAL-P1', 'VAL-P2']

(删除元组)我将能够使用新的列名执行相同的代码行:

testdf1=testdf.groupby(['BRAND'])['VAL-P1','VAL-P2'].sum()

并最终得到:

BRAND     ('VAL', 'Per1')   ('VAL', 'Per2')
  A            10.0              0.155
  B            18.7              17.5
  C            12.1              12.3
  D            8.0               7.0

这里最奇怪的是,如果我使用.mean()代替.sum(), min() or .max(),即使使用元组也一切正常。

任何人都可以解释我如何在python 3.5上使用元组列名进行这样的聚合?

1 个答案:

答案 0 :(得分:2)

我认为你需要使用groupby.agg并传递一个函数来聚合每个组的总和,如下所示:

df = pd.DataFrame({'PROD_TAG':["P_1", "P_2", "P_3", "P_3", "P_4", "P_5"],
                   'BRAND':["A", "A", "B", "B", "C", "D"],
                   'Market':["Modern Trade", "Traditional Trade",   \
                   "Modern Trade", "Traditional Trade", "Modern Trade", "Modern Trade"],
                   ('VAL','Per1'):[4.3, 5.7, 10.0, 8.7, 12.1, 8.0],
                   ('VAL','Per2'):[0.155, 0, 11.2, 6.3, 12.3, 7.0]})

type(df[('VAL','Per1')].name)
#<class 'tuple'>

df.groupby(['BRAND'])[('VAL','Per1'), ('VAL','Per2')].agg(lambda x: x.sum())

       (VAL, Per1)  (VAL, Per2)
BRAND                          
A             10.0        0.155
B             18.7       17.500
C             12.1       12.300
D              8.0        7.000

或者,不重置索引并转换分组器列。因此,由于列[TypeError]的名称不匹配,您可以摆脱 tuple/str

df.groupby(['BRAND'], as_index=False)[('VAL','Per1'), ('VAL','Per2')].sum()

  BRAND  (VAL, Per1)  (VAL, Per2)
0     A         10.0        0.155
1     B         18.7       17.500
2     C         12.1       12.300
3     D          8.0        7.000

但如果您tuplestring agg,则可以像以前一样继续使用df.rename(index=str, columns={('VAL','Per1'): "('VAL','Per1')", \ ('VAL','Per2'): "('VAL','Per2')"}, inplace=True) type(df["('VAL','Per1')"].name) #<class 'str'> df.groupby(['BRAND'])["('VAL','Per1')","('VAL','Per2')"].sum() ('VAL','Per1') ('VAL','Per2') BRAND A 10.0 0.155 B 18.7 17.500 C 12.1 12.300 D 8.0 7.000 功能:

Python 3.5

注意:经过git rerere

测试