Определение правильного порядка строк в Pandas

У меня есть следующий фрейм данных, показывающий взаимосвязь различных объектов в каждой строке.

Ребенок Родитель Ult_Parent Полная семья А032 А001 А039 А001, А032, А039, А040, А041, А043, А043, А045, А046

В столбце «Full_Family» отображается правильная иерархия для всего генеалогического древа от маленького до большого, а не только для объектов в этой конкретной строке. Но следует иметь в виду, что не каждый объект в «Full_Family» появится в «Child/Parent/Ult_Parent», поскольку данные «Full_Family» поступают из другого источника.

Здесь мне нужно решить 2 проблемы:

  1. Порядок Child/Parent/Ult_Parent неправильный. Как на основе столбца «Full_Family» определить правильный порядок?
  2. Если возможно, могу ли я также определить правильный Ult_Parent для семейства во всей таблице, а не в каждой строке. Этот правильный Ult_Parent должен быть объектом, который появился в столбцах Child/Parent/Ult_Parent.

Ниже приведен пример и идеальный результат:

Ребенок Родитель Ult_Parent Полная семья Правильный заказ Correct_Ult_Parent_per_Family А032 А001 А039 А001, А032, А039, А040, А041, А043, А043, А045, А046 А001, А032, А039 А043 А001 А043 А039 А001, А032, А039, А040, А041, А043, А043, А045, А046 А001, А039, А043 А043

Хотя A046 является основным родителем в этом семействе, он не отображается в Child/Parent/Ult_Parent этого фрейма данных, поэтому правильным окончательным родителем для каждого семейства в данном случае является A043.

Цените помощь.

0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Я думаю, это немного отличается от того, что я хочу. Я считаю, что мой пример неудачен. Порядок не является неправильным, потому что позиция Родителя/Дочернего элемента неверна. Это может быть случайно неправильно. Например, Child должен быть Ult_Parent, а Ult_Parent должен быть Child. Дело в том, что нам нужно проверить порядок в Full_Family, чтобы мы могли определить правильный порядок. Итак, я предполагаю, что использование сортировки и исправления порядка Parent > Child > Ult_Parent - это не то, что мне нужно в этом случае. Спасибо за помощь!

L H 29.06.2024 23:10

@LH IIUC, вторая часть моего ответа посвящена этому, используя специальный ключ для sorted.

e-motta 29.06.2024 23:12

Только что проверил! Извините, я не знаю, почему я не видел остальные части. Это работает так, как я ожидаю. Спасибо :)

L H 29.06.2024 23:18

@LH Не беспокойтесь, я отредактировал ответ, чтобы добавить его, так что, возможно, поэтому вы его пропустили. Кроме того, поскольку 'Full_Family' не обязательно является возрастающим, я просто понял, что нам нужен другой способ получения 'Correct_Ult_Parent_per_Family' во второй части, поэтому я сейчас редактирую его, чтобы добавить.

e-motta 30.06.2024 00:11

Итак, у меня есть строка, содержащая такой идентификатор, как «008ZY8-E», и я запускаю эту функцию и продолжаю получать эту ошибку KeyError: «008ZY8-E», вы знаете причину, почему?

L H 02.07.2024 14:37

@LH Трудно сказать без дополнительной информации, но, вероятно, ее нет в значении 'Full_Family'.

e-motta 02.07.2024 14:43

Другие вопросы по теме