繁体   English   中英

熊猫更新匹配多个条件的组的行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM