Добавьте значение в фрейме данных в строку на основе другого значения

#python #pandas #dataframe #lookup

#python #панды #фрейм данных #поиск

Вопрос:

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

Например, у меня есть этот фрейм данных:

 import pandas as pd

data = {
    'role': ['primary', 'secondary', 'primary', 'secondary'],
    'serial_number': ['abc', '123', 'def', '456'],
    'primary_serial_number': ['abc', 'abc', 'def', 'def'],
    'physical_id': ['w', 'x', 'y', 'z'],
    'set_id': ['j', 'x', 'k', 'z']
}
df = pd.DataFrame(data = data)

    role    serial_number   primary_serial_number   physical_id set_id
0   primary     abc                  abc                  w       j
1   secondary   123                  abc                  x       x
2   primary     def                  def                  y       k
3   secondary   456                  def                  z       z
 

Вторичные всегда имеют одинаковые physical_id и set_id. Для каждого вторичного элемента я хотел бы иметь set_id соответствующего первичного элемента в той же строке, что и вторичный. Я могу посмотреть это, сопоставив «primary_serial_number» для каждого вторичного с «serial_number» для каждого первичного. Тогда у меня должен быть столбец с надписью «primary_set_id», который имеет значения j, j, k, k.

Я попробовал следующее:

 df['primary_set_id'] = df['primary_serial_number'].apply(
    lambda x: df['set_id'][df['serial_number'] == x])
 

Когда я запускаю это для приведенных выше поддельных данных, я получаю:

Ошибка значения: неверное количество переданных элементов 2, размещение подразумевает 1

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

Ответ №1:

Я думаю, что это должно сделать это

 grps = df.groupby('role')
prim_df = grps.get_group('primary')
sec_df = grps.get_group('secondary')
primsec_df = sec_df.merge(prim_df, left_on = 'primary_serial_number', right_on = 'serial_number')
primsec_df
 

в столбце 'sec_id_y' вы получаете то, что хотите:

 |    | role_x    |   serial_number_x | primary_serial_number_x   | physical_id_x   | set_id_x   | role_y   | serial_number_y   | primary_serial_number_y   | physical_id_y   | set_id_y   |
|---:|:----------|------------------:|:--------------------------|:----------------|:-----------|:---------|:------------------|:--------------------------|:----------------|:-----------|
|  0 | secondary |               123 | abc                       | x               | x          | primary  | abc               | abc                       | w               | j          |
|  1 | secondary |               456 | def                       | z               | z          | primary  | def               | def                       | y               | k          |
 

Я не уверен, насколько эффективно это будет на большом df

Комментарии:

1. Мило! Спасибо. Я заканчиваю созданием отдельных DFS вручную, потому что мой фактический набор данных немного сложнее, чем просто эти две группы, а затем я выполняю некоторую очистку меток столбцов и добавляю его обратно в исходный DF.