首页 > 解决方案 > 熊猫“重新装箱”数据框

问题描述

包含年龄数据的 DataFrame 分列在不同的行中,如下所示:

价值,年龄
 10, 0-4
 20、5-9
 30、10-14
 40、15-19
 ………………

因此,基本上,年龄按 5 年分组。我想要 10 年的垃圾箱,即 0-9,10-19 等。我追求的是价值,但对于基于 10 年的年龄垃圾箱,这些值将是:

价值,年龄
30, 0-9
70、10-19

我可以通过移动和添加并获取结果数据帧的每一行来做到这一点,但是 Pandas 中是否有任何智能、更通用的方法来做到这一点?

标签: pythonpandasbinning

解决方案


这是一个“愚蠢”的版本,基于这个答案- 只需每 2 行求和:

In[0]
df.groupby(df.index // 2).sum()

Out[0]:
   VALUE
0     30
1     70

我说“愚蠢”是因为这种方法没有考虑到年龄限制,它恰好与他们保持一致。因此,假设年龄范围是可变的,或者如果您的数据从 5-9 而不是 0-4 开始,这可能会导致问题。您还必须重命名索引,因为它不清楚。

“更智能”的版本是pd.cut根据每行的年龄实际创建 bin 并使用它对数据进行分组:

In[0]
df['MAX_AGE'] = df['AGE'].str.split('-').str[-1].astype(int)

bins = [0,10,20]
out = df.groupby(pd.cut(df['MAX_AGE'], bins=bins, right=False)).sum().drop('MAX_AGE',axis=1)

Out[0]:
          VALUE
    AGE        
(0, 10]      30
(10, 20]     70

说明

  • 使用pandas.Series.str方法得到每行的最大年龄,存储在一列中"MAX_AGE"
  • bins在 10 年截止时创建
  • 用于根据每行的最大年龄pd.cut分配数据。bins然后groupby在这些垃圾箱上使用并求和。请注意,由于我们指定right = False,索引中描述的 bin 应表示 0-9 和 10-19。

作为参考,这是我使用的数据:

import pandas as pd
    
VALUE = [10,20,30,40,]
AGE = ['0-4','5-9','10-14','15-19']

df = pd.DataFrame({'VALUE':VALUE,
                   'AGE':AGE})

推荐阅读