代码之家  ›  专栏  ›  技术社区  ›  L H

识别Pandas中正确的字符串顺序

  •  0
  • L H  · 技术社区  · 11 月前

    我有一个数据帧如下,显示了每行中不同实体的关系。

    小孩 父母亲 Ult_Pparent 完整家庭(_F)
    A032 A001 A039 A001、A032、A039、A040、A041、A043、A043、A045、A046

    在“Full_Family”列中,它显示了整个家谱从小到大的正确层次结构,而不仅仅是该特定行中的实体。但需要注意的是,并非“Full_Family”中的每个实体都会出现在“Child/PParent/Ult_Pparent”中,因为“Full_Ffamily”数据来自其他来源。

    这里我有两个问题需要解决:

    1. Child/PParent/Ult_Pparent顺序不正确,如何基于“Full_Family”列来确定正确的顺序?
    2. 如果可能的话,我还可以在整个表中而不是每一行中为一个族确定正确的Ult_Pparent吗。此正确的Ult_Pparent必须是已出现在“子”/“父”/“最终父”列中的实体。

    以下是示例和理想结果:

    小孩 父母亲 Ult_Pparent 完整家庭(_F) Correct_Order Correct_Ult_Parent_per_Family
    A032 A001 A039 A001、A032、A039、A040、A041、A043、A043、A045、A046 A001、A032、A039 A043
    A001 A043 A039 A001、A032、A039、A040、A041、A043、A043、A045、A046 A001、A039、A043 A043

    虽然A046是该族中的最终父级,但它不会出现在此数据帧的Child/PParent/Ult_Pparent中,因此在这种情况下,每个族的正确最终父级是A043。

    感谢您的帮助。

    1 回复  |  直到 11 月前
        1
  •  1
  •   e-motta    11 月前

    IIUC,假设该数据帧作为输入:

    import pandas as pd
    
    data = {
        "Child": ["A032", "A001"],
        "Parent": ["A001", "A043"],
        "Ult_Parent": ["A039", "A039"],
        "Full_Family": [
            "A001, A032, A039, A040, A041, A043, A043, A045, A046",
            "A001, A032, A039, A040, A041, A043, A043, A045, A046",
        ],
    }
    
    df = pd.DataFrame(data)
    
      Child Parent Ult_Parent                                        Full_Family
    0  A032   A001       A039  A001, A032, A039, A040, A041, A043, A043, A045...
    1  A001   A043       A039  A001, A032, A039, A040, A041, A043, A043, A045...
    

    您可以使用这种方法:

    df["Correct_Order"] = df.apply(
        lambda row: ", ".join(sorted([row["Parent"], row["Child"], row["Ult_Parent"]])),
        axis=1,
    )
    
    df["Correct_Ult_Parent_per_Family"] = (
        df[["Parent", "Child", "Ult_Parent"]].max(axis=1).max()
    )
    
      Child Parent Ult_Parent                                        Full_Family     Correct_Order Correct_Ult_Parent_per_Family
    0  A032   A001       A039  A001, A032, A039, A040, A041, A043, A043, A045...  A001, A032, A039                          A043
    1  A001   A043       A039  A001, A032, A039, A040, A041, A043, A043, A045...  A001, A039, A043                          A043
    

    如果 'Full_Family' 不一定是按升序排列的,并且您希望尊重其顺序,可以定义一个自定义键 sorted .

    例如,如果 A039 在之前 A032 在里面 'Full_Family' 在第一行中:

    data = {
        "Child": ["A032", "A001"],
        "Parent": ["A001", "A043"],
        "Ult_Parent": ["A039", "A039"],
        "Full_Family": [
            "A001, A039, A032, A040, A041, A043, A043, A045, A046",
            "A001, A032, A039, A040, A041, A043, A043, A045, A046",
        ],
    }
    
    df = pd.DataFrame(data)
    

    使用自定义密钥:

    df["Correct_Order"] = df.apply(
        lambda row: ", ".join(
            sorted(
                [row["Parent"], row["Child"], row["Ult_Parent"]],
                key=lambda x: {
                    val: idx for idx, val in enumerate(row["Full_Family"].split(", "))
                }[x],
            )
        ),
        axis=1,
    )
    
    df["Correct_Ult_Parent_per_Family"] = df["Correct_Order"].str.split().str[-1].max()
    
      Child Parent Ult_Parent                                        Full_Family     Correct_Order Correct_Ult_Parent_per_Family
    0  A032   A001       A039  A001, A039, A032, A040, A041, A043, A043, A045...  A001, A039, A032                          A043
    1  A001   A043       A039  A001, A032, A039, A040, A041, A043, A043, A045...  A001, A039, A043                          A043