объединить столбцы значений манекенов в один столбец (pd.get_dummies в обратном порядке) - PullRequest
0 голосов
/ 28 мая 2018

У меня есть Pandas DataFrame, подобный этому:

id     Apple   Apricot   Banana    Climentine   Orange    Pear    Pineapple
01       1        1         0          0          0         0         0    
02       0        0         1          1          1         1         0 
03       0        0         0          0          1         0         1

Как я могу сгенерировать новый DataFrame, подобный этому?

id     fruits
01     Apple, Apricot
02     Banana, Clementine, Orange, Pear
03     Orange, Pineapple

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

ОК. Я сделал несколько поисков здесь на SO и нашел: https://stackoverflow.com/a/24045425/7386332

Эквивалент здесь был бы просто как 0 оценивается как False внутри понимания.

import pandas as pd

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})


df = (df.set_index('id')
       .apply(lambda row: ', '.join([col for col, b in zip(df.columns, row) if b]), 
              axis=1)
       .reset_index())

Сравнение времени

Маленький набор (выше)

1.37 ms ± 4.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # list comprehensio
1.41 ms ± 2.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # df.dot
3.28 ms ± 81.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) # df.melt

Использование (df = pd.concat([df]*1000)) для имитации большего набора:

36.9 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.dot
39.8 ms ± 369 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # df.melt
84.5 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) # list comprehension
0 голосов
/ 28 мая 2018

Используйте melt, фильтр 1 и значения последнего объединения для групп с ,:

df = pd.DataFrame({
    'id': ['01','02','03'],
    'Apple': [1,0,0],
    'Apricot': [1,0,0],
    'Banana': [0,1,0],
    'Climentine': [0,1,0],
    'Orange': [0,1,1],
    'Pear': [0,1,0],
    'Pineapple': [0,0,1]
})

df = (df.melt('id', var_name='fruits').query('value == 1')
       .groupby('id')['fruits']
       .apply(', '.join)
       .reset_index())

print (df)

#   id                            fruits
#0   1                    Apple, Apricot
#1   2  Banana, Climentine, Orange, Pear
#2   3                 Orange, Pineapple

Для повышения производительности используйте dot для умножения матриц:

df = df.set_index('id')
df = df.dot(df.columns + ', ').str.rstrip(', ').reset_index(name='fruit')
print (df)
   id                             fruit
0  01                    Apple, Apricot
1  02  Banana, Climentine, Orange, Pear
2  03                 Orange, Pineapple
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...