如何在列名称的子组内独立重新排列熊猫数据框的每一行?

时间:2019-04-17 16:14:06

标签: python pandas

我需要在数据帧的同一行中重新排列数据,其中某些列可能没有数据。原始数据框:

  hash   a1   a2   a3    a4    a5    b1    b2    b3    b4    b5
  0      1    2    nan   nan   nan   1     2     3     4     nan
  1      1    nan  nan   nan   nan   1     2     3     nan   nan

我期望具有的数据框:

  hash   a1    a2     a3     a4     a5    b1    b2     b3    b4    b5
  0      nan   nan    nan    1      2     nan   1      2     3     4     
  1      nan   nan    nan    nan    1     nan   nan    1     2     3

2 个答案:

答案 0 :(得分:1)

使用justify函数按组应用lambda函数,按x[0]用于选择列名的首字母,使用axis=1用于按列分组:

df = df.set_index('hash')
f = lambda x: pd.DataFrame(justify(x.values, invalid_val=np.nan, side='right'), 
                           columns=[f'{x.name}{y}' for y in range(1, len(x.columns) + 1)])
df = df.groupby(lambda x: x[0], axis=1).apply(f)
print (df)
   a1  a2  a3   a4   a5  b1   b2   b3   b4   b5
0 NaN NaN NaN  1.0  2.0 NaN  1.0  2.0  3.0  4.0
1 NaN NaN NaN  NaN  1.0 NaN  NaN  1.0  2.0  3.0

答案 1 :(得分:0)

如何在循环中选择一个子集(例如[a1,a2,a3]),然后对子集进行转置并按行对其进行排序,然后再次将其粘在一起。

import numpy as np
import pandas as pd

# dummy data
df = pd.DataFrame(np.random.randint(1, 10, (5, 6)),
                  columns=['a1', 'a2', 'a3', 'b1', 'b2', 'b3'])
# add some nan
df = df.mask(np.random.random(df.shape) < .3)

def rearrange_data_column_wise(df):
    col_ = set([col[0] for col in df.columns])
    df_ = pd.DataFrame()
    for col in col_:
        filter_col = [c for c in df if c.startswith(col)]
        df_sub = df[filter_col].T
        df_sub = pd.DataFrame(np.sort(df_sub.values,  axis=0),
                              index=df_sub.index,
                              columns=df_sub.columns)

        df_ = pd.concat([df_, df_sub.T], axis=1)

    return df_

df = rearrange_data_column_wise(df)
print(df.head())

这将为您提供一个排序的数据框,每个子集的右侧带有NaN

    a1   a2  a3   b1   b2   b3
0  4.0  NaN NaN  3.0  4.0  7.0
1  9.0  NaN NaN  4.0  5.0  9.0
2  6.0  9.0 NaN  2.0  4.0  9.0
3  3.0  7.0 NaN  7.0  9.0  NaN
4  2.0  2.0 NaN  2.0  6.0  NaN

仅供参考,set会更改列的顺序,但是您可以防止显示here