使用更奇怪的结果:熊猫中的 groupby 和 nlargest()
Posted
技术标签:
【中文标题】使用更奇怪的结果:熊猫中的 groupby 和 nlargest()【英文标题】:More bizarre results using: groupby and nlargest() in pandas 【发布时间】:2017-06-18 13:58:59 【问题描述】:这个问题是以下帖子的延伸:select largest N of a column of each groupby group using pandas
让我们使用相同的 df 和所选答案中提出的解决方法。基本上,我正在尝试进行 2 个 groupby 操作并选择每个组中最大的 N。但是,正如您在下面看到的,其中一项操作出现错误。
鉴于原帖在代码中发现了一个错误(see here),我想知道是否还有其他错误或同一错误的另一种表现形式?
不幸的是,在这些问题得到解决和解决之前,我的工作一直处于停滞状态。我们可以请注意这个问题吗?直到明天我才能提供赏金。
df:
'city1': 0: 'Chicago',
1: 'Chicago',
2: 'Chicago',
3: 'Chicago',
4: 'Miami',
5: 'Houston',
6: 'Austin',
'city2': 0: 'Toronto',
1: 'Detroit',
2: 'St.Louis',
3: 'Miami',
4: 'Dallas',
5: 'Dallas',
6: 'Dallas',
'p234_r_c': 0: 5.0, 1: 4.0, 2: 2.0, 3: 0.5, 4: 1.0, 5: 4.0, 6: 3.0,
'plant1_type': 0: 'COMBCYCL',
1: 'COMBCYCL',
2: 'NUKE',
3: 'COAL',
4: 'NUKE',
5: 'COMBCYCL',
6: 'COAL',
'plant2_type': 0: 'COAL',
1: 'COAL',
2: 'COMBCYCL',
3: 'COMBCYCL',
4: 'COAL',
5: 'NUKE',
6: 'NUKE'
你可以使用上面的dict来生成df:pd.DataFrame(dct)
First groupby:似乎产生了有意义的结果
cols = ['city2','plant1_type','plant2_type']
df.set_index(cols).groupby(level=cols)['p234_r_c'].nlargest(1).reset_index()
city2 plant1_type plant2_type p234_r_c
0 Toronto COMBCYCL COAL 5.0
1 Detroit COMBCYCL COAL 4.0
2 St.Louis NUKE COMBCYCL 2.0
3 Miami COAL COMBCYCL 0.5
4 Dallas NUKE COAL 1.0
5 Dallas COMBCYCL NUKE 4.0
6 Dallas COAL NUKE 3.0
第二组:产生错误。唯一的区别是使用city1
而不是city2
。
cols = ['city1','plant1_type','plant2_type']
df.set_index(cols).groupby(level=cols)['p234_r_c'].nlargest(1).reset_index()
错误结果:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-443-6426182b55e1> in <module>()
----> 1 test1.set_index(cols).groupby(level=cols)['p234_r_c'].nlargest(1).reset_index()
C:\Users\user1\Anaconda3\lib\site-packages\pandas\core\series.py in reset_index(self, level, drop, name, inplace)
967 else:
968 df = self.to_frame(name)
--> 969 return df.reset_index(level=level, drop=drop)
970
971 def __unicode__(self):
C:\Users\user1\Anaconda3\lib\site-packages\pandas\core\frame.py in reset_index(self, level, drop, inplace, col_level, col_fill)
2944 level_values = _maybe_casted_values(lev, lab)
2945 if level is None or i in level:
-> 2946 new_obj.insert(0, col_name, level_values)
2947
2948 elif not drop:
C:\Users\user1\Anaconda3\lib\site-packages\pandas\core\frame.py in insert(self, loc, column, value, allow_duplicates)
2447 value = self._sanitize_column(column, value)
2448 self._data.insert(loc, column, value,
-> 2449 allow_duplicates=allow_duplicates)
2450
2451 def assign(self, **kwargs):
C:\Users\user1\Anaconda3\lib\site-packages\pandas\core\internals.py in insert(self, loc, item, value, allow_duplicates)
3508 if not allow_duplicates and item in self.items:
3509 # Should this be a different kind of error??
-> 3510 raise ValueError('cannot insert %s, already exists' % item)
3511
3512 if not isinstance(loc, int):
ValueError: cannot insert plant2_type, already exists
最后:
如何使用['city2','plant1_type','plant2_type']
获得groupby 结果中的city1
列,以及使用['city1','plant1_type','plant2_type']
获得groupby 结果中的city2
列?
我想知道使用['city2','plant1_type','plant2_type']
的groupby 对应的city1
值和使用['city1','plant1_type','plant2_type']
的groupby 对应的city2
值。
更新:
为什么下面的结果有完全不同的结构?唯一的区别是city2
用在#A中,city1
用在#B中。
一)
cols = ['city2','plant1_type','plant2_type']
test1.set_index(cols).groupby(level=cols)['p234_r_c'].nlargest(1)
city2 plant1_type plant2_type
Toronto COMBCYCL COAL 5.0
Detroit COMBCYCL COAL 4.0
St.Louis NUKE COMBCYCL 2.0
Miami COAL COMBCYCL 0.5
Dallas NUKE COAL 1.0
COMBCYCL NUKE 4.0
COAL NUKE 3.0
Name: p234_r_c, dtype: float64
B)
cols2 = ['city1','plant1_type','plant2_type']
test1.set_index(cols2).groupby(level=cols2)['p234_r_c'].nlargest(1)
city1 plant1_type plant2_type city1 plant1_type plant2_type
Austin COAL NUKE Austin COAL NUKE 3.0
Chicago COAL COMBCYCL Chicago COAL COMBCYCL 0.5
COMBCYCL COAL Chicago COMBCYCL COAL 5.0
NUKE COMBCYCL Chicago NUKE COMBCYCL 2.0
Houston COMBCYCL NUKE Houston COMBCYCL NUKE 4.0
Miami NUKE COAL Miami NUKE COAL 1.0
Name: p234_r_c, dtype: float64
【问题讨论】:
【参考方案1】:试试这个:
In [76]: df.groupby(cols2)['p234_r_c'].nlargest(1).reset_index(level=3, drop=True).reset_index()
Out[76]:
city1 plant1_type plant2_type p234_r_c
0 Austin COAL NUKE 3.0
1 Chicago COAL COMBCYCL 0.5
2 Chicago COMBCYCL COAL 5.0
3 Chicago NUKE COMBCYCL 2.0
4 Houston COMBCYCL NUKE 4.0
5 Miami NUKE COAL 1.0
坦率地说,我不理解以下行为:
In [77]: df.set_index(cols2).groupby(level=cols2)['p234_r_c'].nlargest(1)
Out[77]:
city1 plant1_type plant2_type city1 plant1_type plant2_type
Austin COAL NUKE Austin COAL NUKE 3.0
Chicago COAL COMBCYCL Chicago COAL COMBCYCL 0.5
COMBCYCL COAL Chicago COMBCYCL COAL 5.0
NUKE COMBCYCL Chicago NUKE COMBCYCL 2.0
Houston COMBCYCL NUKE Houston COMBCYCL NUKE 4.0
Miami NUKE COAL Miami NUKE COAL 1.0
Name: p234_r_c, dtype: float64
地点:
In [78]: cols2
Out[78]: ['city1', 'plant1_type', 'plant2_type']
【讨论】:
感谢您的帖子。我对这种行为的回答是 - 为什么在 groupby 操作中选择哪些列很重要?['city1', 'plant1_type', 'plant2_type']
和 ['city2', 'plant1_type', 'plant2_type']
有什么区别?为什么相同的 groupby 代码适用于一个操作而不适用于另一个操作?
知道如何解决当前的错误,使用['city2','plant1_type','plant2_type']
找到groupby
对应的city1
值,使用['city1','plant1_type','plant2_type']
找到groupby
对应的city2
值。
'city1'
和 'city2'
之间的区别在于,在一种情况下,它是“真正的” groupby 操作,而在另一种情况下,每个组的大小实际上是 1。这显然不是一个理由(这就是为什么有一个未解决的问题),只是一个解释;然后,reset_index(level=3)
建议我的@MaxU 是您正在寻找的解决方法。
@PietroBattiston - 感谢您的解释。所以,我可以做df.loc[df.groupby(cols2)['p234_r_c'].nlargest(1).reset_index().level_3]
通过groupby 从原始数据框中检索选定的行,其中cols2 = ['city1', 'plant1_type', 'plant2_type']
。但是,我不确定如何为 cols = ['city2', 'plant1_type', 'plant2_type']
执行此操作。
***.com/questions/42030468/… 中提出的解决方法以上是关于使用更奇怪的结果:熊猫中的 groupby 和 nlargest()的主要内容,如果未能解决你的问题,请参考以下文章