如何通过在其他列中查找非空值来创建列

How to create columns by looking not null values in other columns

我有数据框,需要将非空值放入列中。

例如:可能有超过5列,但每行不超过2个非空值

df1 = pd.DataFrame({'A' : [np.nan, np.nan, 'c',np.nan, np.nan, np.nan], 
                   'B' : [np.nan, np.nan, np.nan, 'a', np.nan,'e'],
                   'C' : [np.nan, 'b', np.nan,'f', np.nan, np.nan], 
                   'D' : [np.nan, np.nan, 'd',np.nan, np.nan, np.nan], 
                   'E' : ['a', np.nan, np.nan,np.nan, np.nan, 'a']})

   A   B   C   D   E  
NaN NaN NaN NaN   a       
NaN NaN   b NaN NaN       
  c NaN NaN   d NaN      
NaN   a   f NaN NaN      
NaN NaN NaN NaN NaN   
NaN   e NaN NaN   a      

我的预期输出:要生成 4 个新列,Other_1; Other_1_姓名; Other_2; Other_2_name,如果没有空值,值会去Other_1或Other_2,列名会去Other_1_name或Other_2_name .如果值为 NaN,则保留 4 列行 NaN。

  A   B   C   D   E  Other_1 Other_1_name Other_2 Other_2_name
NaN NaN NaN NaN   a       a          E       NaN        NaN 
NaN NaN   b NaN NaN       b          C       NaN        NaN 
  c NaN NaN   d NaN       c          A        d           D
NaN   a   f NaN NaN       a          B        f           C  
NaN NaN NaN NaN NaN     NaN         NaN      NaN        NaN  
NaN   e NaN NaN   a       e          B         a          E  

使用DataFrame.melt with missing values by DataFrame.dropna for unpivot, then add counter columns by GroupBy.cumcount and reshape by DataFrame.unstack:

df2 = df1.melt(ignore_index=False,var_name='name',value_name='val').dropna()[['val','name']]

g = df2.groupby(level=0).cumcount().add(1)
df2 = df2.set_index(g,append=True).unstack().sort_index(level=1,axis=1,sort_remaining=False)
df2.columns = df2.columns.map(lambda x: f'Other_{x[1]}_{x[0]}')
print (df2)
  Other_1_val Other_1_name Other_2_val Other_2_name
0           a            E         NaN          NaN
1           b            C         NaN          NaN
2           c            A           d            D
3           a            B           f            C
5           e            B           a            E

最后追加到原始:

df = df1.join(df2)
print (df)
     A    B    C    D    E Other_1_val Other_1_name Other_2_val Other_2_name
0  NaN  NaN  NaN  NaN    a           a            E         NaN          NaN
1  NaN  NaN    b  NaN  NaN           b            C         NaN          NaN
2    c  NaN  NaN    d  NaN           c            A           d            D
3  NaN    a    f  NaN  NaN           a            B           f            C
4  NaN  NaN  NaN  NaN  NaN         NaN          NaN         NaN          NaN
5  NaN    e  NaN  NaN    a           e            B           a            E