缺少值时如何旋转和重命名已连接的级别列?

时间:2019-05-07 06:11:05

标签: python pandas pivot

我有一个数据框。每个ID都有几个代码,每个代码都有统计信息。并非所有ID都具有其他人拥有的所有代码。 我需要旋转数据框,以便每个ID都有一行,每对代码状态对都有一列。

如何使用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

更新 我发布的代码有误。 对于代码“ a”,代码应为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 个答案:

答案 0 :(得分:1)

DataFrame.set_indexDataFrame.unstackDataFrame.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

答案 1 :(得分:0)

如果您只有2列(最小值和最大值),则可以执行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