объединить несколько столбцов в один

#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