【问题标题】:pandas comma separated hierarchy groupby sumpandas 逗号分隔层次结构 groupby sum
【发布时间】:2020-08-08 04:49:36
【问题描述】:

我有以下分层数据的数据格式。可以有多个单层和可变深度的行。我试图得到一个结果,在 col_2 中我们看到实例的所有低级的总和。

使用简单的 groupby 不起作用,因为它不了解层次结构。我尝试将 col_1 拆分为多个列,分别命名为 level-1 到 level-6(深度),因此 groupby level-1 到 level-6,但尽管数据帧是多索引,但结果仍然不正确。

分离前代码:
df.groupby(["col_1"], as_index=False).sum()

分离后的代码:
df.groupby(["level-1","level-2","level-3","level-4","level-5","level-6"], as_index=False).sum()

任何帮助将不胜感激!

感谢@Yo_Chris 到目前为止更新:

import pandas as pd
# sample data
df = pd.DataFrame({'Col1': ['PUU', 'PUU;UT', 'PUU;UT', 'PUU;UT;AHU', 'PUU;UT;AHU;CSP', 'PUU;AS', 'PUU;PREV', 'PUU;TECHNOLOGY', 'PUU;TECHNOLOGY', 'PUU;TECHNOLOGY;SPEC'],
                  'Col2': [1000,1000,50,500,250,100,1000,300,500,900]})

# groupby, sum and invert 
s = df.groupby('Col1')['Col2'].sum()[::-1]
# groupby, cumsum and invert
s.groupby(s.index.str[0]).cumsum()[::-1])```

# this results in the following:

Col1
PUU                    5600
PUU;AS                 4600
PUU;PREV               4500
PUU;TECHNOLOGY         3500
PUU;TECHNOLOGY;SPEC    2700
PUU;UT                 1800
PUU;UT;AHU              750
PUU;UT;AHU;CSP          250
Name: Col2, dtype: int64

而我们想要的是:

PUU                    5600
PUU;AS                  100
PUU;PREV               1000
PUU;TECHNOLOGY         1700
PUU;TECHNOLOGY;SPEC     900
PUU;UT                 1800
PUU;UT;AHU              750
PUU;UT;AHU;CSP          250

【问题讨论】:

  • 为什么 a;b 在您的预期输出 1800 而不是 1750 中?为什么g;h 900 而不是800?
  • 因为有 2 个实例 a;b = 1000 + 50 ,加上 a;b;c 和 a;b;c;d 500+250 = 1800。类似地,g = g 的 2 个实例+ g;h = 300+500+900 = 1700 因为这里的 h 是 g 的子代。
  • 知道了,我只是拿差价不加。

标签: python-3.x pandas pandas-groupby hierarchical-data multi-index


【解决方案1】:

最终通过将 col_1 拆分为每个深度的单独列来解决此问题。然后按每列(深度 1、2、..6)和所有结果数据帧的串联进行分组。不是很干净,但可以正常工作!

【讨论】:

    【解决方案2】:

    我根据您的样本数据做了一些假设。 col1 始终是由分号分隔的单个字符,并且 col1 始终是排序的: col1 不能是 ['a;b;c', 'a', 'a;b'...]

    # sample data
    df = pd.DataFrame({'Col1': ['a', 'a;b', 'a;b', 'a;b;c', 'a;b;c;d', 'e', 'f', 'g', 'g', 'g;h'],
                      'Col2': [1000,1000,50,500,250,100,1000,300,500,900]})
    
    # groupby, sum and invert 
    s = df.groupby('Col1')['Col2'].sum()[::-1]
    # groupby, cumsum and invert
    s.groupby(s.index.str[0]).cumsum()[::-1]
    
    # return a pd.Series
    
    Col1
    a          2800
    a;b        1800
    a;b;c       750
    a;b;c;d     250
    e           100
    f          1000
    g          1700
    g;h         900
    Name: Col2, dtype: int64
    

    【讨论】:

    • 您好,感谢您的回复!是否可以修改此代码以处理 col_1 不是单个字符而是由“;”分隔的实际单词的数据?能否请您解释一下此解决方案的工作原理?
    • @AliAdiby 当然,它可以修改为在 col1 不是单个字符但我需要更多信息的情况下工作。请使用新的示例数据(不是图像,而是我如何创建框架)更新您的问题。现在所有代码都是在 col1 上进行分组,获取每个组的总和并反转帧。然后,第二行,对第一个字符上新形成的系列进行分组,获取每组的累积和,然后将系列反转回正常。
    • 感谢您再次查看克里斯。我已经在问题更新中更新了示例
    • 我对您的预期输出感到有些困惑...我的假设是 PUU 是父级,那么您为什么不想对所有内容进行 cumsum 呢?您的预期输出将第二个元素视为父元素。这就是您想要总结所有内容的方式(基于列表中的第二个元素)
    • 另外,您可以列出第三个元素而不列出第二个元素吗? PUU;UT 后跟 PUU;AHU 后跟 PUU;UT;AHU;CSP
    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    相关资源
    最近更新 更多