#python #pandas #merge
#python #панды #слияние
Вопрос:
У меня есть фрейм данных, подобный этому (я пытаюсь его адаптировать, поскольку он на испанском языке, и копировать вставить не помогает)
Question 1 opt. A Question 1 opt. B Question 1 opt. C Question 2 opt. A Question 2 opt. B
0 NaN NaN yes NaN NaN
1 NaN None NaN Uber NaN
2 NaN NaN NaN Didi NaN
Итак, многие столбцы на самом деле являются ответом на один и тот же вопрос, только другим вариантом. То, что я хотел бы сделать, это какое-то слияние, подобное этому:
Question 1 Question 2
0 yes NaN
1 None Uber
2 NaN Didi
То есть каким-то образом суммировать все ответы на каждый вопрос в один столбец (при условии, что все они являются взаимоисключающими). Пометка каждого из них была бы плюсом. Я считаю, что цикл for мог бы это сделать, но я очень плохо его реализую, и циклы настоятельно рекомендуется не использовать в python.
Комментарии:
1. Что происходит, когда параметры не являются взаимоисключающими? Что вы пробовали с циклами? Они не поощряются, но нет ничего лучше цикла, чтобы показать ваше реальное намерение.
2. Посмотрите на использование
pd.wide_to_long
.3. Я действительно очень плох в циклах. Так что я только подумал об этом. Я не получил ничего существенного.
Ответ №1:
Попробуйте это:
(pd.wide_to_long(df.reset_index(), ['Question 1', 'Question 2'], 'index', 'Option', sep=' ', suffix='.*')
.dropna(how='all')
.max(level=1)
.reset_index())
Вывод:
Option Question 1 Question 2
0 opt. C yes NaN
1 opt. A NaN Uber
2 opt. B None NaN
Ответ №2:
Вы можете использовать str.extract
для извлечения части вопроса из столбцов, затем groupby
фрейма данных в этой извлеченной серии axis=1
и агрегирования с помощью first
:
g = df.columns.str.extract(r'(Question d )', expand=False)
out = df.groupby(g, axis=1).first()
Результат:
Question 1 Question 2
0 yes NaN
1 None Uber
2 NaN Didi
Комментарии:
1. Отличный ответ! 1 Как у тебя дела, мой друг? Быть в безопасности и оставаться здоровым?
2. Спасибо. Я в порядке. Мои самые теплые пожелания чудесного Рождества и счастливого Нового года 🙂
Ответ №3:
Используйте fillna для замены None и NaN на emtpy string . Тогда rest — это простая конкатенация
Код:
import pandas as pd
import numpy as np
data = {'Question 1 opt. A' : [np.nan, np.nan, np.nan],
'Question 1 opt. B' : [np.nan, None, np.nan],
'Question 1 opt. C' : ['yes', np.nan, np.nan],
'Question 2 opt. A' : [np.nan, 'Uber','Didi'],
'Question 2 opt. B' : [np.nan, np.nan, np.nan]}
df = pd.DataFrame(data)
print(df)
df.fillna('', inplace=True)
df['Question 1'] = df['Question 1 opt. A'] df['Question 1 opt. B'] df['Question 1 opt. C']
df['Question 2'] = df['Question 2 opt. A'] df['Question 2 opt. B']
print(df)
Вывод:
Question 1 opt. A Question 1 opt. B Question 1 opt. C Question 2 opt. A Question 2 opt. B
0 NaN NaN yes NaN NaN
1 NaN NaN NaN Uber NaN
2 NaN NaN NaN Didi NaN
Question 1 opt. A Question 1 opt. B Question 1 opt. C Question 2 opt. A Question 2 opt. B Question 1 Question 2
0 yes yes
1 Uber Uber
2 Didi Didi