Как повернуть и переименовать объединенные столбцы уровня, если отсутствуют значения? - PullRequest
1 голос
/ 07 мая 2019

У меня есть датафрейм. У каждого идентификатора есть несколько кодов, у каждого кода есть статистика. Не все идентификаторы имеют все коды, которые есть у других. Мне нужно повернуть фрейм данных, чтобы у каждого идентификатора была одна строка со столбцом для каждой пары код-статистика.

Как мне сделать это наиболее эффективно, используя pandas 0.24.2 и python 3.6?

Спасибо

import pandas as pd

df = pd.DataFrame({'id':[11, 11, 11, 12, 12, 13], 'code':['a', 'b', 'c', 'a', 'b', 'a'], 'max':[111, 112, 113, 221, 222, 333], 'min':[10, 11, 12, 21, 22, 33]})

df
Results in
    id code  max  min
0   11    a  111   11
1   11    b  112   12
2   11    c  113   13
3   12    a  221   21
4   12    b  222   22
5   13    c  333   33

Мне нужно преобразовать его в

id a_max a_min b_max b_min c_max c_min
11   111    11   112    12   113    13     
12   221    21   222    22  None  None
13  None  None  None  None   333    33

обновление У меня ошибка в коде, который я разместил. Коды должны быть 11, 12, 13, а не 10, 11, 12 для кода «а».

import pandas as pd
df = pd.DataFrame({'id':[11, 11, 11, 12, 12, 13], 'code':['a', 'b', 'c', 'a', 'b', 'a'], 'max':[111, 112, 113, 221, 222, 333], 'min':[11, 12, 13, 21, 22, 33]})
df

Ответы [ 2 ]

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

Используйте DataFrame.set_index с DataFrame.unstack и DataFrame.sort_index, затем сглаживайте MultiIndex и конвертируйте индекс в столбец с помощью reset_index:

df1 = df.set_index(['id','code']).unstack().sort_index(axis=1, level=1)
df1.columns = df1.columns.map('_'.join)
df1 = df1.reset_index()
print (df1)
   id  max_a  min_a  max_b  min_b  max_c  min_c
0  11  111.0   10.0  112.0   11.0  113.0   12.0
1  12  221.0   21.0  222.0   22.0    NaN    NaN
2  13  333.0   33.0    NaN    NaN    NaN    NaN

Если возможно дублирование пар по необходимости, необходимо агрегирование по DataFrame.pivot_table:

df = pd.DataFrame({'id':[11, 11, 11, 12, 12, 13], 
                   'code':['a', 'a', 'c', 'a', 'b', 'a'], 
                   'max':[111, 112, 113, 221, 222, 333], 
                   'min':[10, 11, 12, 21, 22, 33]})
print (df)
   id code  max  min
0  11    a  111   10 <--- 11, a
1  11    a  112   11 <--- 11, a
2  11    c  113   12
3  12    a  221   21
4  12    b  222   22
5  13    a  333   33

df1 = df.pivot_table(index='id',columns='code', aggfunc='mean').sort_index(axis=1, level=1)
#alternative
#df1 = df.groupby(['id','code']).mean().unstack().sort_index(axis=1, level=1)
df1.columns = df1.columns.map('_'.join)
df1 = df1.reset_index()
print (df1)
   id  max_a  min_a  max_b  min_b  max_c  min_c
0  11  111.5   10.5    NaN    NaN  113.0   12.0
1  12  221.0   21.0  222.0   22.0    NaN    NaN
2  13  333.0   33.0    NaN    NaN    NaN    NaN
0 голосов
/ 07 мая 2019

Для решения этой проблемы вы можете выполнить двухэтапную операцию, если у вас есть только 2 столбца мин. И макс.

# convert the data from long to wide format for max and min
df_max = df.pivot(index="id", columns="code", values="max").reset_index()
df_min = df.pivot(index="id", columns="code", values="min").reset_index()

# join the max and min dataframe with a suffix
merged_df = pd.merge(df_max, df_min, on="id", how="outer", suffixes=("_max", "_min"))

выход:

code  id  a_max  b_max  c_max  a_min  b_min  c_min
0     11  111.0  112.0  113.0   11.0   12.0   13.0
1     12  221.0  222.0    NaN   21.0   22.0    NaN
2     13  333.0    NaN    NaN   33.0    NaN    NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...