#python #pandas #dataframe
Вопрос:
Прежде всего, всем привет! Это первый раз, когда я на самом деле публикую вопрос в StackOverflow, поэтому, если я слишком конкретен / слишком общий, я был бы признателен за совет :).
У меня есть фрейм данных Pandas, содержащий некоторые данные авторизации SAP, в котором столбец может содержать что-то вроде «значений-заполнителей», которые должны быть преобразованы в соответствующие им значения. И на данный момент у меня действительно закончились идеи..
Например, в фрейме данных, показанном ниже, у меня есть две роли, каждая из которых содержит объект (авторизации) F_BKPF_BUK
с полями ACTVT
и ABC
. ABC
характеризуется «значением-заполнителем» $EKGRP
для LOW
.
ROLE OBJECT FIELD LOW HIGH
0 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ACTVT 03 NaN
1 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC $EKGRP NaN
2 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ACTVT 03 NaN
3 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC $EKGRP NaN
Теперь сложность в том, что заполнитель $EKGRP
обычно преобразуется в зависящие от роли (!) множественные значения. Фрейм данных для $EKGRP выглядит следующим образом:
ROLE VARBL LOW HIGH
0 D:AS:MY_FANCY_ROLE_A $EKGRP U01 U99
1 D:AS:MY_FANCY_ROLE_A $EKGRP P01 P99
2 D:AS:MY_FANCY_ROLE_A $EKGRP P01 P29
3 D:AS:MY_FANCY_ROLE_B $EKGRP P01 P00
4 D:AS:MY_FANCY_ROLE_B $EKGRP N01 N99
5 D:AS:MY_FANCY_ROLE_B $EKGRP I01 I99
Итак, конечный результат, которого я хотел бы достичь, — заменить все вхождения заполнителя соответствующими значениями для обоих столбцов LOW
и HIGH
:
ROLE OBJECT FIELD LOW HIGH
0 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ACTVT 03 NaN
1 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC U01 U99
2 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC P01 P99
3 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC P01 P29
4 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ACTVT 03 NaN
5 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC P01 P00
6 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC N01 N99
7 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC I01 I99
Начал использовать Pandas всего несколько недель назад, вскоре я достиг точки, когда у меня закончились идеи для этой конкретной проблемы. Мое последнее предположение состояло в том, чтобы, возможно, использовать df.apply(...)
для проверки наличия заполнителя, но этот подход не решит проблему, заключающуюся в том, что после нахождения заполнителя исходная строка должна быть продублирована несколько раз, а их LOW
HIGH
значения и будут изменены на соответствующие значения.
На какую функцию pandas вы бы порекомендовали мне взглянуть поближе? Я хотел бы, насколько это возможно, избегать итераций по строкам и ознакомиться с «лучшими практиками» для такого рода проблем.
Ответ №1:
Если возможно, используйте внешнее соединение по столбцу LOW
from df1
с ROLE
первой копией LOW
в VARBL
in DataFrame.assign
, затем замените отсутствующие значения в DataFrame.fillna
(необходимо удалить _
в столбцах для соответствия) и в последний раз удалите ненужные столбцы:
df = (df1.assign(VARBL = df1['LOW'])
.merge(df2, on=['ROLE','VARBL'], how='outer', suffixes=('_','')))
df[['LOW','HIGH']] = (df[['LOW','HIGH']].fillna(df[['LOW_','HIGH_']]
.rename(columns=lambda x: x.strip('_'))))
df = df.drop(['LOW_','HIGH_','VARBL'], axis=1)
print (df)
ROLE OBJECT FIELD LOW HIGH
0 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ACTVT 03 NaN
1 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC U01 U99
2 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC P01 P99
3 D:AS:MY_FANCY_ROLE_A F_BKPF_BUK ABC P01 P29
4 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ACTVT 03 NaN
5 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC P01 P00
6 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC N01 N99
7 D:AS:MY_FANCY_ROLE_B F_BKPF_BUK ABC I01 I99