使用组约束将列值向左移动

eal*_*iaj 5 python dataframe pandas

我有一个“潜在”的大型DataFrame,

     A    B_1    B_2    B_3    C_1    C_2    C_3
0  231  text2  text3    NaN  date4  date1    NaN
1  443  NaN    NaN    text1  date2    NaN    NaN
2  456  text1  text1  text2  NaN    date3  date1
Run Code Online (Sandbox Code Playgroud)

为了最小化某些NaNs,我想将所有数据向左移动,从而能够忽略所有NaN列。但是,此移位必须保留在适当的组内,这意味着,只要单元格不在B_1或B_2列中,只要它不移位到C_1等,都没有关系。

我最后要说的是

     A    B_1    B_2    B_3    C_1    C_2    
0  231  text2  text3    NaN  date4  date1
1  443  text1    NaN    NaN  date2    NaN
2  456  text1  text1  text2  date3  date1
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 2

每组使用justifyMultiIndex函数,仅在列中需要:

df = df.set_index('A')
df.columns = df.columns.str.split('_', expand=True)

f = lambda x: pd.DataFrame(justify(x.values, invalid_val=np.nan), 
                           index=x.index, columns=x.columns)
df = df.groupby(axis=1, level=0).apply(f)
print (df)
         B                    C            
         1      2      3      1      2    3
A                                          
231  text2  text3    NaN  date4  date1  NaN
443  text1    NaN    NaN  date2    NaN  NaN
456  text1  text1  text2  date3  date1  NaN
Run Code Online (Sandbox Code Playgroud)

进而:

df1.columns = [f'{a}_{b}' for a, b in df1.columns]
df1 = df1.reset_index()
Run Code Online (Sandbox Code Playgroud)

结合之前答案的解决方案:

g = df.groupby('A').cumcount() + 1
df1 = df.set_index(['A', g]).unstack()

f = lambda x: pd.DataFrame(justify(x.values, invalid_val=np.nan), 
                           index=x.index, columns=x.columns)
df1 = df.groupby(axis=1, level=0).apply(f)

df1.columns = [f'{a}_{b}' for a, b in df1.columns]
df1 = df1.reset_index()
Run Code Online (Sandbox Code Playgroud)