[英]Pandas update row of a group matching multiple conditions
pandas 的新手和第一个关于 stakeoverflow 的问题(请耐心等待):我有一个 df 个人,有时会在一个家庭 ID 下重新组合。 这里感兴趣的数据是家庭内的性别和状态,如下所示:
行号 | 家庭身份证 | 地位 | 性别 |
---|---|---|---|
1 | Fam_1 | 头 | 未定 |
2 | Fam_1 | 妻子 | 女性 |
3 | Fam_1 | 孩子 | 未定 |
4 | Fam_1 | 孩子 | 男性 |
5 | 头 | 男性 | |
6 | Fam_2 | 头 | 女性 |
7 | Fam_2 | 孩子 | 女性 |
8 | Fam_3 | 头 | 未定 |
9 | Fam_3 | 妻子 | 女性 |
10 | Fam_3 | 孩子 | 男性 |
11 | Fam_3 | 头 | 未定 |
注:见第5行:有些人是单身(没有FamilyID),见Fam_3:有些家庭有几个人(相关的成年人)。
最初,我需要创建一个新列 Gender_Inferred,其中 Gender_Inferred = 男性仅适用于有妻子(处于状态)且只有一个负责人(Fam_3 由于第 11 行而被排除)的家庭的未确定性别(第 1 行)的负责人。
我可以为有妻子的家庭制作面具,如下所示:
mask1 = df.groupby('FamilyID')['Status'].transform(lambda r: r.eq('wife').any())
组合标准头/未确定更新的掩码:
mask2 = (df['Status'] == 'self') & (df['Gender'] == 'undeter mind')
然后我申请条件:
df['Gender_Inferred'] = np.nan
df['Gender_Inferred'] = np.where(mask1 & mask2, 'male', df['Gender'])
但是我无法为“家庭只有 1 个状态=头和性别=未确定”的条件创建掩码 3。 “几乎”好像一个人想做 'df.groupby('FamilyID')[['006_File1_Relation','004_File1_Gender']].transform(lambda r: (r[0].eq('self') & r[1].eq('undetermined')).any())' 但当然这不是正确的代码。
我需要:
行号 | 家庭身份证 | 地位 | 性别 | Gender_Inferred |
---|---|---|---|---|
1 | Fam_1 | 头 | 未定 | 男性 |
2 | Fam_1 | 妻子 | 女性 | 女性 |
3 | Fam_1 | 孩子 | 未定 | 未定 |
4 | Fam_1 | 孩子 | 男性 | 男性 |
5 | 头 | 未定 | 未定 | |
6 | Fam_2 | 头 | 女性 | 女性 |
7 | Fam_2 | 孩子 | 女性 | 女性 |
8 | Fam_3 | 头 | 未定 | 未定 |
9 | Fam_3 | 妻子 | 女性 | 女性 |
10 | Fam_3 | 孩子 | 男性 | 男性 |
11 | Fam_3 | 头 | 未定 | 未定 |
使用 groupby 屏蔽或使用 np.where 更新(经常导致不匹配长度错误)不是必需的,我会对任何可行的解决方案感到满意。
谢谢
样本输入
df = pd.DataFrame([
[1, "Fam_1", "head", "undetermined"],
[2, "Fam_1", "wife", "female"],
[3, "Fam_1", "child", "undetermined"],
[4, "Fam_1", "child", "male"],
[5, np.NaN, "head", "male"],
[6, "Fam_2", "head", "female"],
[7, "Fam_2", "child", "female"],
[8, "Fam_3", "head", "undetermined"],
[9, "Fam_3", "wife", "female"],
[10, "Fam_3", "child", "male"],
[11, "Fam_3", "head", "undetermined"],
], columns=["RowID", "FamilyID", "Status", "Gender"])
将 FamilyID - nans 标记为 Single
df.FamilyID.replace(np.NaN, "Single", inplace=True)
计算家庭中的户主人数
heads_df = df.loc[df.Status == "head"].groupby("FamilyID")["Status"].count().reset_index(name="HeadCount")
将信息合并回原始df
df = df.merge(heads_df, on="FamilyID", how="left")
使用 shift 添加新列
df["NextMember" ] = df.Status.shift(-1)
准备好所有信息后,运行查询并分配
df.loc[
(df.FamilyID != "Single")
& (df.Status == "head")
& (df.NextMember == "wife")
& (df.Gender == "undetermined")
& (df.HeadCount == 1)
, "Gender"] = "male"
删除新创建的列
df.drop(["HeadCount", "NextMember"], inplace=True, axis=1)
输出
RowID FamilyID Status Gender
0 1 Fam_1 head male
1 2 Fam_1 wife female
2 3 Fam_1 child undetermined
3 4 Fam_1 child male
4 5 Single head male
5 6 Fam_2 head female
6 7 Fam_2 child female
7 8 Fam_3 head undetermined
8 9 Fam_3 wife female
9 10 Fam_3 child male
10 11 Fam_3 head undetermined
注意:从上面给出的示例输入中,我假设状态 == 妻子将跟随状态 == 头。 如果我的假设是错误的,请让我知道。 在这种情况下,该解决方案将不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.