Как выполнить множественный поиск на основе значений столбца и заполнить пустой столбец?

У меня есть фрейм данных с 4 столбцами. Мне нужно выполнить несколько поисков, а затем присвоить значение в одном из столбцов. Вот образец данных:

CategoryId  ParentCategoryId  SourceCategoryId  SourceParentCategoryId
         1                                 100                       0
         2                                 101                       0
         3               9.0               102                     108
         4              20.0               103                     100
         5               4.0               104                     103
         6                                 105                     103
         7                                 106                     103
         8                                 107                     103
         9                                 108                       0
        10                                 109                     108
        11                                 110                     103
        12                                 111                     103
        13                                 112                     103
        14                                 113                     100
        15                                 114                     113
        16                                 115                     113
        17                                 116                     113
        18                                 117                     113
        19                                 118                     113
        20                                 100                     113

Я пытаюсь заполнить значения в столбце ParentCategoryId следующей логикой: Для каждой строки мы будем искать значение в SourceParentCategoryId, и если оно равно нулю, мы его пропустим. Если значение в SourceParentCategoryId отличается от нуля, как в строке 3, мы видим, что SourceParentCategoryId равно 108. Затем мне нужно найти это значение в SourceCategoryId и определить, к какому CategoryId оно принадлежит. В приведенном мной примере мы видим, что CategoryId имеет CategoryId 9, что является значением, которое мне нужно вставить в строку 3 в моем столбце ParentCategoryId.

По той же логике строка 4 имеет SourceParentCategoryId = 100, что основано на SourceCategoryId, имеющем CategoryId = 20, а затем значение 20 добавляется в строку 4 в столбце ParentCategoryId.

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

Не могли бы вы помочь мне решить эту проблему или хотя бы дать мне несколько советов?

Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
0
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Предполагая, что у вас еще нет данных в столбце ParentCategoryId, вы можете использовать следующий подход:

  • Самостоятельно присоединитесь к фрейму данных на SourceParentCategoryId == SourceCategoryId.
  • Если совпадений несколько, то самообъединение может иметь повторяющиеся записи. Ограничьте это, сохранив первую запись.
  • Сбросить значения для SourceParentCategoryId == 0.
df = df.merge(df, left_on = "SourceParentCategoryId", right_on = "SourceCategoryId", how = "left", suffixes=("", "_delete"))

# If there are multiple matches, then the self join may have repeated records. Limit this by retaining first record.
df = df.groupby(["CategoryId", "SourceCategoryId", "SourceParentCategoryId"])["CategoryId_delete"].first().reset_index()

df = df.rename(columns = {"CategoryId_delete": "ParentCategoryId"})

# Reset values for `SourceParentCategoryId == 0`.
df["ParentCategoryId"] = df.apply(lambda row: None if row["SourceParentCategoryId"] == 0 else row["ParentCategoryId"], axis=1)

Выход:

    CategoryId  SourceCategoryId  SourceParentCategoryId  ParentCategoryId
0            1               100                       0               NaN
1            2               101                       0               NaN
2            3               102                     108              9.00
3            4               103                     100              1.00
4            5               104                     103              4.00
5            6               105                     103              4.00
6            7               106                     103              4.00
7            8               107                     103              4.00
8            9               108                       0               NaN
9           10               109                     108              9.00
10          11               110                     103              4.00
11          12               111                     103              4.00
12          13               112                     103              4.00
13          14               113                     100              1.00
14          15               114                     113             14.00
15          16               115                     113             14.00
16          17               116                     113             14.00
17          18               117                     113             14.00
18          19               118                     113             14.00
19          20               100                     113             14.00
Ответ принят как подходящий

Используйте DataFrame.drop_duplicates для удаления дубликатов с помощью SourceCategoryId, поэтому возможное сопоставление SourceParentCategoryId отфильтровано без 0 значений в SourceParentCategoryId с помощью Series.map:

m = df['SourceParentCategoryId'].ne(0)

s = df.drop_duplicates('SourceCategoryId').set_index('SourceCategoryId')['CategoryId']
df['ParentCategoryId'] = df.loc[m, 'SourceParentCategoryId'].map(s)
print (df)
    CategoryId  ParentCategoryId  SourceCategoryId  SourceParentCategoryId
0            1               NaN               100                       0
1            2               NaN               101                       0
2            3               9.0               102                     108
3            4               1.0               103                     100
4            5               4.0               104                     103
5            6               4.0               105                     103
6            7               4.0               106                     103
7            8               4.0               107                     103
8            9               NaN               108                       0
9           10               9.0               109                     108
10          11               4.0               110                     103
11          12               4.0               111                     103
12          13               4.0               112                     103
13          14               1.0               113                     100
14          15              14.0               114                     113
15          16              14.0               115                     113
16          17              14.0               116                     113
17          18              14.0               117                     113
18          19              14.0               118                     113
19          20              14.0               100                     113

Для сохранения последних повторяющихся значений используйте параметр keep='last':

m = df['SourceParentCategoryId'].ne(0)

s = df.drop_duplicates('SourceCategoryId', keep='last').set_index('SourceCategoryId')['CategoryId']
df['ParentCategoryId'] = df.loc[m, 'SourceParentCategoryId'].map(s)
print (df)
    CategoryId  ParentCategoryId  SourceCategoryId  SourceParentCategoryId
0            1               NaN               100                       0
1            2               NaN               101                       0
2            3               9.0               102                     108
3            4              20.0               103                     100
4            5               4.0               104                     103
5            6               4.0               105                     103
6            7               4.0               106                     103
7            8               4.0               107                     103
8            9               NaN               108                       0
9           10               9.0               109                     108
10          11               4.0               110                     103
11          12               4.0               111                     103
12          13               4.0               112                     103
13          14              20.0               113                     100
14          15              14.0               114                     113
15          16              14.0               115                     113
16          17              14.0               116                     113
17          18              14.0               117                     113
18          19              14.0               118                     113
19          20              14.0               100                     113

@Azharkan и Jezrael - спасибо вам обоим за эти два подхода. Эти работы. Я был так далек от понимания этого. Еще раз спасибо.

Slavisha84 11.01.2023 15:46

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