Как изменить фрейм данных на основе значений столбцов

#pandas #dataframe

Вопрос:

Я хочу добавить отношения в столбец «отношения» на основе rel_list. В частности, для каждого кортежа, т. Е. («a», «b»), я хочу заменить значение столбца «отношения» на » b «в первой строке, но без дублирования, что означает, что для 2-й строки не заменяйте» на «a», поскольку они считаются дублированными. Следующий код работает не совсем правильно:

 import pandas as pd  data = {  "names": ['a', 'b', 'c', 'd'],  "ages": [50, 40, 45, 20],  "relations": ['', '', '', ''] } rel_list = [('a', 'b'), ('a', 'c'), ('c', 'd')]  df = pd.DataFrame(data)  for rel_tuple in rel_list:  head = rel_tuple[0]  tail = rel_tuple[1]   df.loc[df.names == head, 'relations'] = tail  print(df)  

Текущий результат df является:

 names ages relations 0 a 50 c 1 b 40  2 c 45 d 3 d 20   

Однако правильным является:

 names ages relations 0 a 50 b 0 a 50 c 1 b 40  2 c 45 d 3 d 20   

Есть новые строки, которые необходимо добавить. 2 — й ряд в этом случае, как и выше. Как это сделать?

Ответ №1:

Вы можете создать фрейм данных и merge :

 (df.drop('relations', axis=1)  .merge(pd.DataFrame(rel_list, columns=['names', 'relations']),  on='names',  how='outer'  )  # .fillna('') # uncomment to replace NaN with empty string  )  

Выход:

 names ages relations 0 a 50 b 1 a 50 c 2 b 40 NaN 3 c 45 d 4 d 20 NaN  

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

1. вы это проверяли? У меня нет изменений в df после вашего кода.

2. @marlon да, это работает нормально, но он не изменяет фрейм данных на месте, это возвращает новый фрейм данных. Вам нужно назначить переменную 😉

Ответ №2:

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

 import pandas as pd  data = {  "names": ['a', 'b', 'c', 'd'],  "ages": [50, 40, 45, 20],  "relations": ['', '', '', ''] } rel_list = [('a', 'b'), ('a', 'c'), ('c', 'd')]  df = pd.DataFrame(data) new_df = pd.DataFrame(data) new_df.loc[:, 'relations'] = ''  for head, tail in rel_list:  new_row = df[df.names == head]  new_row.loc[:,'relations'] = tail  new_df = new_df.append(new_row)  print(new_df)  

Выход:

 names ages relations 0 a 50  1 b 40  2 c 45  3 d 20  0 a 50 b 0 a 50 c 2 c 45 d   

Затем, при необходимости, в конце концов вы можете удалить все строки без значения в разделе «отношения».:

 new_df = new_df[new_df['relations']!='']