使用更奇怪的结果:熊猫中的 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()的主要内容,如果未能解决你的问题,请参考以下文章

熊猫:groupby 和转换与日期时间

如何在熊猫中过滤 groupby 的结果

熊猫:GroupBy .pipe() 与 .apply()

熊猫 .plot.hist() 和 .groupby()

如何在熊猫中的 groupby().mean() 之后获取索引值列表?

当计数为零时熊猫 groupby 以及如何在结果中包含零值