Python 3.x groupby python类型错误:无序类型:tuple()<;str()

Python 3.x groupby python类型错误:无序类型:tuple()<;str(),python-3.x,pandas,Python 3.x,Pandas,我最初用Python2.7编写了一些代码,但现在改用Python3.5。 我想从几列中聚合数字数据,并按其余列或至少一列进行分组 以下是我的初始数据帧“testdf”: 最后两列标题是元组(谢谢)。Per1和Per2代表各自的期间 我想执行一行代码,它以前在python 2.7上工作过: testdf=testdf.groupby(['BRAND'])[('VAL','P1'),('VAL','P2')].sum() 由于列标题和提升的元组类型,它不起作用: TypeError: unorde

我最初用Python2.7编写了一些代码,但现在改用Python3.5。 我想从几列中聚合数字数据,并按其余列或至少一列进行分组

以下是我的初始数据帧“testdf”:

最后两列标题是元组(谢谢)。Per1和Per2代表各自的期间

我想执行一行代码,它以前在python 2.7上工作过:

testdf=testdf.groupby(['BRAND'])[('VAL','P1'),('VAL','P2')].sum()
由于列标题和提升的元组类型,它不起作用:

TypeError: unorderable types: tuple() < str()
(删除元组)我将能够使用新列名执行同一行代码:

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()或.max()
,即使使用元组,一切都可以正常工作

有人能告诉我如何在python 3.5上使用元组列名称进行聚合吗?

我认为您需要使用并传递一个函数来聚合每个组的总和,如图所示:

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
但是,如果将
元组
列添加到
字符串
,则可以像以前一样继续,而无需使用
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
df.rename(index=str,columns={('VAL','Per1'):“('VAL','Per1')”\
('VAL','Per2'):“('VAL','Per2')”},inplace=True)
类型(df[“('VAL','Per1')”)].name)
#
df.groupby(['BRAND'])[“('VAL','Per1')”,“('VAL','Per2')”].sum()
('VAL','Per1')('VAL','Per2'))
烙印
A 10.0 0.155
B 18.7 17.500
C 12.1 12.300
D 8.0 7.000

注意:
Python3.5

中测试,我相信这可能是一个bug。差不多一年过去了,我忘记了这个问题,最近又回忆了它,只是通过提出GH问题来解决这个bug。但在提高之前,我想检查它是否仍然存在。这表明这个问题不再是实际的=)嗨,伙计,非常感谢你的回答,它真的很有效。但我仍然不明白为什么python会“比较”某些东西,我是说tuple()groupby中使用
as_index=True
默认值,该值返回带有组标签的对象作为索引。因此,您基本上是在比较导致
TypeError
的两种不同类型。因此,通常的做法是将列标签更改为
str
,这样就可以避免这些错误情况。是的,我得到了一个要点,python确实比较了“导致类型错误的两种不同类型”。但我不明白为什么它会“比较”列名。。。这是一个简单的汇总,按品牌进行汇总,比较什么?确实,你提出了一个非常有效的观点。我也不明白为什么要处理docs/GH问题。我建议你要么把这个例子发布在网站上,要么创建一个新的帖子来说明这个异常现象,这里的专家可以指导你找到解决方案。好的,我想我会在GH问题中提出它。再次感谢你,尼克!
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
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
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