Конвертируйте фрейм данных из длинного формата в широкоформатный и динамически именуйте столбцы - PullRequest
1 голос
/ 07 мая 2019

Я преобразую фрейм данных из длинного в широкоформатный формат, однако проблема, с которой я сталкиваюсь, заключается в создании правильного числа переведенных столбцов и динамическом переименовании столбцов нового фрейма данных.

Итак, допустим, у меня естьПримерный кадр данных выглядит следующим образом:

data = {'name':['Tom', 'nick', 'Tom', 'nick','Tom'], 'id':[20, 21, 20, 21,22], 'plan' : [100,101,102,101,100], 'drug' : ['a','b','b','c','a']}

df = pd.DataFrame(data)
drug id  name   plan
a    20  Tom    100
b    21  nick   101
b    20  Tom    102
c    21  nick   101
a    22  Tom    100

Поэтому для каждого имени и идентификатора я хочу создать несколько столбцов для плана и лекарств.Например, есть 3 разных плана и 3 разных препарата, поэтому в идеале я должен получить 6 новых столбцов, которые указывают, был ли принят конкретный план / препарат или нет.

Я пытался перейти с длинного на широкий, но яне получить желаемый результат.Преобразование длинных в широкие:

df1 = df.groupby(['name','id'])['plan', 'drug'].apply(lambda x: pd.DataFrame(x.values)).unstack().reset_index()

Фактический результат:

name    id  0   1    0   1
Tom     20  100 102  a  b
nick    21  101 101  b  c
Tom     22  100 None a  None

Ожидаемый результат:

   name    age  100 101 102   a   b  c 
   Tom     20   1   0    1    1   1  0
   Tom     22   1   0    0    1   0  0
   nick    21   0   1    0    0   1  1

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Использование get_dummies с max:

df1 = pd.get_dummies(df.set_index(['name','id']).astype(str)).max(level=[0,1]).reset_index()
print(df1)
   name  id  plan_100  plan_101  plan_102  drug_a  drug_b  drug_c
0   Tom  20         1         0         1       1       1       0
1  nick  21         0         1         0       0       1       1
2   Tom  22         1         0         0       1       0       0

df2 = (pd.get_dummies(df.set_index(['name','id'])
        .astype(str), prefix='', prefix_sep='')
        .max(level=[0,1])
        .reset_index())
print(df2)
   name  id  100  101  102  a  b  c
0   Tom  20    1    0    1  1  1  0
1  nick  21    0    1    0  0  1  1
2   Tom  22    1    0    0  1  0  0

РЕДАКТИРОВАТЬ: Решение с DataFrame.pivot_table, concatи DataFrame.clip:

df1 = df.pivot_table(index=['name','id'], 
                     columns=['plan'], 
                      aggfunc='size',
                      fill_value=0)

df2 = df.pivot_table(index=['name','id'], 
                     columns=['drug'], 
                      aggfunc='size',
                      fill_value=0)

df = pd.concat([df1, df2], axis=1).clip(upper=1).reset_index()
print(df)
   name  id  100  101  102  a  b  c
0   Tom  20    1    0    1  1  1  0
1   Tom  22    1    0    0  1  0  0
2  nick  21    0    1    0  0  1  1
0 голосов
/ 07 мая 2019
import pandas as pd

data = {
    'name':['Tom', 'nick', 'Tom', 'nick','Tom'],
    'id':[20, 21, 20, 21,22],
    'plan': [100,101,102,101,100],
    'drug': ['a','b','b','c','a']
}

df = pd.DataFrame(data)

plans = df.groupby(['name', 'id', 'plan']).size().unstack()
drugs = df.groupby(['name', 'id', 'drug']).size().unstack()

merged_df = pd.merge(plans, drugs, left_index=True, right_index=True)

merged_df = merged_df.fillna(0)

получить значения plan и drug для каждого name и id. (вот для чего size(), а затем unstack())

, а затем просто объедините их по их индексу (который установлен на name и id).

используйте fillna для замены NaN на 0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...