#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]
Это должно работать для нескольких возможных имен для данного столбца.