根据列值转置DF列-Pandas

时间:2019-10-21 10:58:12

标签: python-3.x pandas

我的df看起来像这样,

        param       per     per_date    per_num             
    0   XYZ         1.0     2018-10-01  11.0                
    1   XYZ         2.0     2017-08-01  15.25               
    2   XYZ         1.0     2019-10-01  11.25               
    3   XYZ         2.0     2019-08-01  15.71               
    4   XYZ         3.0     2020-10-01  11.50
    5   XYZ         NaN     NaN         NaN               
    6   MMG         1.0     2021-10-01  11.75               
    7   MMG         2.0     2014-01-01  14.00
    8   MMG         3.0     2021-10-01  12.50               
    9   MMG         1.0     2014-01-01  15.00
    10  LKG         NaN     NaN         NaN               
    11  LKG         NaN     NaN         NaN

我需要这样的输出

  param per_1 per_date_1 per_num_1 per_2 per_date_2 per_num_2 per_3 per_date_3 per_num_3
0 XYZ   1     2018-10-01 11.0      2     2017-08-01 15.25     NaN   NaN        NaN        
1 XYZ   1     2019-10-01 11.25     2     2019-08-01 15.71     3     2020-10-01 11.50
2 XYZ   NaN   NaN        NaN       NaN   NaN        NaN       NaN   NaN        NaN
4 MMG   1     2021-10-01 11.75     2     2014-01-01 14.00     3     2021-10-01 12.50
5 MMG   1     2014-01-01 15.00     NaN   NaN        NaN       NaN   NaN        NaN
6 LKG   NaN   NaN        NaN       NaN   NaN        NaN       NaN   NaN        NaN

如果看到param列具有重复的值,则将根据这些值创建转置的列名。同样,一旦param值以1开头,就会创建一条新记录。我该如何实现?

1 个答案:

答案 0 :(得分:1)

这里的主要问题是最后NaN组中的LKG个-首先用counter创建的cumcount替换缺失值,然后分配给新列per1

s = df['per'].isna().groupby(df['param']).cumsum()
df = df.assign(per1=df['per'].fillna(s).astype(int))
print (df)
   param  per    per_date  per_num  per1
0    XYZ  1.0  2018-10-01    11.00     1
1    XYZ  2.0  2017-08-01    15.25     2
2    XYZ  1.0  2019-10-01    11.25     1
3    XYZ  2.0  2019-08-01    15.71     2
4    XYZ  3.0  2020-10-01    11.50     3
5    XYZ  NaN         NaN      NaN     1
6    MMG  1.0  2021-10-01    11.75     1
7    MMG  2.0  2014-01-01    14.00     2
8    MMG  3.0  2021-10-01    12.50     3
9    MMG  1.0  2014-01-01    15.00     1
10   LKG  NaN         NaN      NaN     1
11   LKG  NaN         NaN      NaN     2

然后用比较组MultiIndex创建1,并用unstack进行累加和整形:

g = df['per1'].eq(1).cumsum()
df = df.set_index(['param', 'per1',g]).unstack(1).sort_index(axis=1, level=1)
df.columns = [f'{a}_{b}' for a, b in df.columns]
df = df.reset_index(level=1, drop=True).reset_index()
print (df)
  param  per_1  per_date_1  per_num_1  per_2  per_date_2  per_num_2  per_3  \
0   LKG    NaN         NaN        NaN    NaN         NaN        NaN    NaN   
1   MMG    1.0  2021-10-01      11.75    2.0  2014-01-01      14.00    3.0   
2   MMG    1.0  2014-01-01      15.00    NaN         NaN        NaN    NaN   
3   XYZ    1.0  2018-10-01      11.00    2.0  2017-08-01      15.25    NaN   
4   XYZ    1.0  2019-10-01      11.25    2.0  2019-08-01      15.71    3.0   
5   XYZ    NaN         NaN        NaN    NaN         NaN        NaN    NaN   

   per_date_3  per_num_3  
0         NaN        NaN  
1  2021-10-01       12.5  
2         NaN        NaN  
3         NaN        NaN  
4  2020-10-01       11.5  
5         NaN        NaN