Сопоставьте имя столбца, хранящееся в другом фрейме данных, и замените его идентификатором

#python #pandas #data-manipulation

#питон #панды #манипулирование данными #python #pandas

Вопрос:

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

Основная таблица выглядит следующим образом:

 Question               ID

gender                 1
sex                    1
what is your gender    1
sexual orientation     1
marital status         2
occupation             3
whats you job          3
  

df1 выглядит следующим образом:

 gender         marital status  occupation

Male           Single          Doctor
Male           Divorced        Engineer
  

Желаемый результат

    1            2                 3                 

   Male        Single            Doctor
   Male        Divorced          Engineer
  

также, если в df1 появляется какая-либо новая переменная, у которой нет идентификатора, указанного в таблице основных данных, ей следует присвоить новый идентификатор, а имя и идентификатор переменной будут обновлены в главной таблице

например.

df2 выглядит следующим образом:

 gender         marital status  country

Male           Single          India
Male           Divorced        UK
  

желаемый df2 :

 1                 2              4

Male           Single          India
Male           Divorced        UK
  

обновленная главная таблица будет:

 Question               ID

gender                 1
sex                    1
what is your gender    1
sexual orientation     1
marital status         2
occupation             3
whats you job          3
country                4
  

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

1. Как насчет других вопросов, которые имеют тот же идентификатор, например, пол, каков ваш пол и сексуальная ориентация?

2. @JayPeerachai итак, в основном в другом наборе данных, если какая-либо переменная имеет какое-либо имя, например, для пола или сексуальной ориентации, ее следует заменить на id = 1 только потому, что все эти переменные ссылаются на одно и то же.

Ответ №1:

Используйте DataFrame.rename by Series для задания имен новых столбцов по другим данным:

 df2 = df1.rename(columns=df.set_index('Question')['ID'])
print (df2)
      1         2         3
0  Male    Single    Doctor
1  Male  Divorced  Engineer
  

Редактировать:

В Question значениях в df есть дубликаты, поэтому необходимо создать уникальные Question значения. Одним из возможных решений является удаление дубликатов с помощью DataFrame.drop_duplicates , вот примеры данных, чтобы посмотреть, как это работает:

 print (df)
              Question  ID
0               gender  10 <-duplicates, change ID for test
1               gender  15 <-duplicates, change ID for test
2  what is your gender   1
3   sexual orientation   1
4       marital status   2
5           occupation   3
6        whats you job   3
  

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

 print (df[df.duplicated('Question', keep=False)])
  Question  ID
0   gender  10
1   gender  15
  

Удалили дубликаты и сохранили первую строку dupe, здесь ID=10 :

 print (df.drop_duplicates('Question').set_index('Question')['ID'])
Question
gender                 10
what is your gender     1
sexual orientation      1
marital status          2
occupation              3
whats you job           3
Name: ID, dtype: int64

df21 = df1.rename(columns=df.drop_duplicates('Question').set_index('Question')['ID'])
print (df21)
     10        2         3 
0  Male    Single    Doctor
1  Male  Divorced  Engineer
  

Удалили дубликаты и сохранили первую строку dupe, здесь ID=15 :

 print (df.drop_duplicates('Question', keep='last').set_index('Question')['ID'])
Question
gender                 15
what is your gender     1
sexual orientation      1
marital status          2
occupation              3
whats you job           3
Name: ID, dtype: int64

df22 = df1.rename(columns=df.drop_duplicates('Question', keep='last').set_index('Question')['ID'])
print (df22)
     15        2         3 
0  Male    Single    Doctor
1  Male  Divorced  Engineer


print (df.set_index('Question')['ID'].to_dict())
{'gender': 15, 'what is your gender': 1, 'sexual orientation': 1, 'marital status': 2, 'occupation': 3, 'whats you job': 3}



df22 = df1.rename(columns=df.set_index('Question')['ID'].to_dict())
print (df22)
     15        2         3 
0  Male    Single    Doctor
1  Male  Divorced  Engineer
  

EDIT1: Если значения в главном фрейме данных не существуют и необходимо сначала добавить их, используйте:

 print (df)
              Question  ID
0               gender   1
1                  sex   1
2  what is your gender   1
3   sexual orientation   1
4       marital status   2
5           occupation   3
6        whats you job   3

print (df1) 
  gender marital status country  code1  code2
0   Male         Single   India      4      7
1   Male       Divorced      UK      3      5
  

Получите все столбцы, которые не существуют в df['Question'] :

 cols = df1.columns.difference(df['Question'].tolist(), sort=False)
print (cols)
Index(['country', 'code1', 'code2'], dtype='object')
  

Добавьте ID следующий по максимальному значению:

 df3 = pd.DataFrame({'Question':cols, 
                    'ID': np.arange(df['ID'].max()   1, len(cols)   df['ID'].max()   1)})
print (df3) 
  Question  ID
0  country   4
1    code1   5
2    code2   6
  

Добавьте к оригиналу master DataFrame :

 df = pd.concat([df, df3], ignore_index=True)
print (df)
              Question  ID
0               gender   1
1                  sex   1
2  what is your gender   1
3   sexual orientation   1
4       marital status   2
5           occupation   3
6        whats you job   3
7              country   4
8                code1   5
9                code2   6
  

Последнее использование оригинального решения:

 df2 = df1.rename(columns=df.set_index('Question')['ID'])
print (df2)
      1         2      4  5  6
0  Male    Single  India  4  7
1  Male  Divorced     UK  3  5
  

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

1. @HemantSain — Можете ли вы протестировать df2 = df1.rename(columns=df.set_index('Question')['ID'].to_dict())

2. @HemantSain — Ответ был отредактирован для поиска возможных решений.

3. @jezrael да, если несколько дубликатов с одинаковыми ID , то проблем нет, в противном случае требуется предварительная обработка 1 :).

4. @jezrael большое спасибо, to_dict сработал, не могли бы вы изучить обновленный вопрос, было бы здорово, если бы вы могли помочь мне и со второй частью вопроса

5. @HemantSain — Не понимаю, откуда python знает, country что 4 такое? Это означает, что последнее значение в master table есть 3 , поэтому используется 3 1=4 ?

Ответ №2:

Вы можете выполнить переименование, используя идентификатор соответствующего вопроса:

 df1.columns = [int(master[master.Question==c]['ID'].values) for c in df1.columns]
  

Это должно работать для нескольких возможных имен для данного столбца.