Python Pandas копирование набора ячеек в пределах кадра данных на основе соответствующего ключа - PullRequest
1 голос
/ 02 марта 2020

Мои знания по Pandas относительно ограничены, и я многого достиг с небольшим фундаментом + вся помощь в SO. Это первый раз, когда я попал в тупик.

Я пытаюсь найти наиболее эффективный способ сделать следующее:

У меня один df ~ 150000 строк с ~ 40 столбцами.

Вот примерный кадр данных, с которым можно работать для исследования решения:

   UniqueID     CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     123      12          1113
1  413-45365    1     889      75          6748
2  413-21165    8     554      13          4536
3  413-24354    1     387      35          7649
4  413-34658    2     121      88          2468
5  413-36889    4     105      76          3336
6  413-23457    5     355      42          7894
7  413-30089    5     146      10          9112
8  413-41158    5     453      91          4545
9  413-51015    9     654      66          2232

Один из столбцов является уникальным идентификатором, остальные столбцы содержат данные, соответствующие к объекту этого идентификатора. Пример:

Я определил отношение в стиле слияния между объектами вне DF, и теперь мне нужно вставить данные там, где это отношение существует, из «родительского» идентификатора во все его «дочерние» идентификаторы .

Если я определил, что 413-23457 является родителем 413-20012 и 413-21165, мне нужно скопировать значения из родительского элемента только в столбцах WEIGHT, VOLUME и PRODUCTIVITY (но не UniqueID или CST) для дочерних объектов. Я также определяю, что 413-41158 является родителем 413-45365 и 413-51015.

Я должен сделать это для многих наборов этих типов ассоциаций по всему фрейму данных.

Я пытался манипулировать большим количеством примера кода для вставки между кадрами данных, но некоторые из моих требований затрудняют поиск достаточно полезного образца. Я также могу представить, как я создаю объекты всего, используя .itterows (), а затем сопоставляю и вставляю соответственно в al oop. Но, отказавшись от .iterrows () для прошлых решений и отметив, сколько времени это может занять, я не думаю, что смогу применить это здесь и выдержать его для больших наборов данных.

Любая помощь будет принята с благодарностью.


Редактировать с дополнительным содержимым в соответствии с предлагаемым решением

Если перегруппировать входной фрейм данных для более случайной сортировки строк, предложенные ответы на самом деле не справлюсь (моя вина в том, что я не смог лучше отобразить фактический набор данных для этого тестового образца).

Начальный кадр данных:

   UniqueID     CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     123      12          1113
1  413-45365    1     889      75          6748
2  413-21165    8     554      13          4536
3  413-24354    1     387      35          7649
4  413-34658    2     121      88          2468
5  413-36889    4     105      76          3336
6  413-23457    5     355      42          7894
7  413-30089    5     146      10          9112
8  413-41158    5     453      91          4545
9  413-51015    9     654      66          2232

Текущее предлагаемое решение:

parent_child_dict = {
    '413-51015': '413-41158',
    '413-21165': '413-23457',
    '413-45365': '413-41158',
    '413-20012': '413-23457'
}

(df.merge(df.UniqueID
           .replace(parent_child_dict),
         on='UniqueID',
         how='right')
   .set_index(df.index)
   .assign(UniqueID=df.UniqueID,
          CST=df.CST)
)

Результирующий фрейм данных:

    UniqueID   CST  WEIGHT  VOLUME  PRODUCTIVITY
0  413-20012    3     387      35          7649
1  413-45365    1     121      88          2468
2  413-21165    8     105      76          3336
3  413-24354    1     355      42          7894
4  413-34658    2     355      42          7894
5  413-36889    4     355      42          7894
6  413-23457    5     146      10          9112
7  413-30089    5     453      91          4545
8  413-41158    5     453      91          4545
9  413-51015    9     453      91          4545

Результат не тот, который ожидался сейчас, когда строки расположены в случайном порядке, и я не понимаю, что произошло. Строка с UniqueID 413-45365 была предназначена для зеркального отображения данных для 413-41158, но имеет некоторую комбинацию данных (121, 88, 2468), которой нет ни в одной из других строк или даже ячеек в начальном DF.

1 Ответ

0 голосов
/ 02 марта 2020

Первое, что я хотел бы сделать, это включить ваши родительско-дочерние отношения в словарь. и тогда мы можем использовать replace и merge:

# create a dictionary of parent-child relationship
parent_child_dict = {}
for parent_id in parent_objects:
    children = get_merge(parent_id)
    for child in children:
        child_id = get_object_info(child)
        # update dict
        parent_child_dict[child_id] = parent_id

# parent_child_dict = {
#     '413-20012': '413-23457',
#     '413-21165': '413-23457',
#     '413-45365': '413-41158',
#     '413-51015': '413-41158'
# }

# merge and copy data back
(df.merge(df.UniqueID
           .replace(parent_child_dict),
         on='UniqueID',
         how='right')
   .set_index(df.index)
   .assign(UniqueID=df.UniqueID,
          CST=df.CST)
)

Выход:

     UniqueID  CST  WEIGHT  VOLUME  PRODUCTIVITY
1   413-23457    5     355      42          7894
2   413-20012    3     355      42          7894
3   413-21165    8     355      42          7894
4   413-24354    1     387      35          7649
5   413-34658    2     121      88          2468
6   413-36889    4     105      76          3336
7   413-30089    5     146      10          9112
9   413-41158    5     453      91          4545
10  413-45365    1     453      91          4545
11  413-51015    9     453      91          4545
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...