【问题标题】:Pandas groupby results - move some grouped column values into rows of new data framePandas groupby 结果 - 将一些分组的列值移动到新数据框的行中
【发布时间】:2020-06-11 18:48:11
【问题描述】:

我看到了许多类似的问题,但找不到直接解决我的问题的方法。

我正在使用一个 pandas 数据框,其中包含非营利组织的组成捐助者的联系信息。数据有家庭和个人。大多数家庭都有成员个人,但并非所有个人都与家庭相关联。没有将 Household 与容器 Individuals 相关联的数据,因此我尝试根据其他数据(家庭街道地址、电话号码、电子邮件等)进行匹配。

数据框的简化版本如下所示:

Constituent Id     Type          Home Street
1234567            Household     123 Main St.
2345678            Individual    123 Main St.
3456789            Individual    123 Main St.
4567890            Individual    433 Elm Rd.
0123456            Household     433 Elm Rd.
1357924            Individual    500 Stack Ln.
1344444            Individual    500 Stack Ln.

我使用groupby 来对成分进行分组。在这种情况下,通过 Home Street。我试图确保我只获得包含多个记录的分组(以排除与家庭无关的个人)。我正在使用类似的东西:

df1 = df[df.groupby('Home Street').filter(lambda x: len(x)>1)

我想做的是以某种方式将分组的数据框导出到一个新的数据框,其中首先包含家庭成员 ID,然后是任何个人成员 ID。如果分组中没有家庭,则将个人选区放置在适当的位置。上面我的数据集的输出如下所示:

Household    Individual  Individual
1234567      2345678     3456789
0123456      4567890
             1357924     1344444

我玩过迭代 groupby 对象,但我觉得我错过了一些简单的方法来完成我的任务。

【问题讨论】:

  • 您是否希望将所有单独的列分开?
  • 是的,我希望将个人分开,无论他们是否有与之关联的家庭(我的示例输出的最后一行显示类似的内容)。
  • 将数据框拆分为包含个人和家庭的行。对两者执行 groupby,而不是用个人扩展 df 中的分组列,而不是加入两个单独的数据框。

标签: python pandas dataframe


【解决方案1】:

应该这样做

df['Type'] = df['Type'] + '_' + (df.groupby(['Home Street','Type']).cumcount().astype(str))
df.pivot_table(index='Home Street', columns='Type', values='Constituent Id', aggfunc=lambda x: ' '.join(x)).reset_index(drop=True)

输出

Type Household_0 Individual_0 Individual_1
0        1234567      2345678      3456789
1        0123456      4567890          NaN
2            NaN      1357924      1344444

【讨论】:

  • 非常接近。我得到的家庭和个人专栏比组中的多。家庭栏应该只有一个,但有很多。原始 groupby 或我的数据框中的内容;我在找。
  • 从听起来你可能每个地址有不止一个家庭
  • 差不多。我之前已将 NaN 字段替换为“无”,并且匹配为重复地址。
  • 太好了,如果这解决了您的问题,请接受它作为正确答案,以帮助希望在未来解决类似问题的人!
  • 是的,只是想完成它并确保它有效。再次感谢。
【解决方案2】:

IIUC,我们可以使用 groupby agg(list) 并使用 .joinexplode 进行一些重新整形

s = df.groupby(["Home Street", "Type"]).agg(list).unstack(1).reset_index(
    drop=True
).droplevel(level=0, axis=1).explode("Household")

df1 = s.join(pd.DataFrame(s["Individual"].tolist()).add_prefix("Indvidual_")).drop(
    "Individual", axis=1
)


print(df1.fillna(' '))

  Household Indvidual_0 Indvidual_1
0   1234567     2345678     3456789
1   0123456     4567890            
2               1357924     1344444

或者我们可以放弃连接并将Household 转换为您的索引。

df1 = pd.DataFrame(s["Individual"].tolist(), index=s["Household"])\
                 .add_prefix("Individual_")
print(df1)

          Individual_0 Individual_1
Household                          
1234567        2345678      3456789
0123456        4567890         None
NaN            1357924      1344444

【讨论】:

  • 谢谢,这看起来是正确的道路。目前,explode() 会抛出一个 ValueError:“列必须是唯一的”。我在 df 中只有唯一的列,所以我正在调查那部分。
猜你喜欢
  • 2012-08-25
  • 2023-01-30
  • 1970-01-01
  • 2016-10-13
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多