Pandas 水平折叠数据框

Pandas collapse dataframe horizontally

我有以下 table 个布尔值:

df1 = pd.DataFrame(data={'w': [True, False, False], 
                         'x': [False, True, False],
                         'y': [True, True, True],
                         'z': [True, False, True]},
                         index=pd.Series([1, 2, 3], name='index'))
index w x y z
1 True False True True
2 False True True False
3 False False True True

我创建了一个新的 table,其宽度与 df1 相同:

pd.DataFrame(columns=[f'column{num}' for num in range(1, len(df1.columns) + 1)])
column1 column2 column3 column4

我想做的是折叠 df1 中的列,这样对于每一行,我只显示具有 True 值的列:

index column1 column2 column3 column4
1 w y z NA
2 x y NA NA
3 y z NA NA

尝试:

out = np.full(df1.shape, np.nan, dtype='object')

# mask valid columns for each row
mask = np.arange(df1.shape[1]) < df1.sum(1).values[:,None]

out[mask] = np.where(df1, df1.columns, np.nan)[df1]

out = pd.DataFrame(out)

dotstr.split 的一种方式:

import numpy as np

df2 = df1.dot(df1.columns+",")
         .str.split(",", expand=True)
         .replace(r'^\s*$', np.nan, regex=True)
         .rename_axis(None)
df2.columns = [f'column{num}' for num in range(1, len(df2.columns)+1)]

>>> df2

    column1 column2 column3 column4
1         w       y       z     NaN
2         x       y     NaN     NaN
3         y       z     NaN     NaN

您可以先使用技巧乘法将列名映射到单元格 (True -> 1, 1*'w' -> 'w' / False -> 0, 0*'w' -> '')

然后使用自定义键对行进行独立排序(isinstance(w, float) 会将 NaNs/floats 推到最后)

cols = [f'column{num}' for num in range(1, len(df1.columns) + 1)]
(df1*df1.columns).where(df1).apply(lambda r: pd.Series(sorted(r, key=lambda x: isinstance(x, float)),
                                                       index=cols), axis=1)

输出:

      column1 column2 column3  column4
index                                 
1           w       y       z      NaN
2           x       y     NaN      NaN
3           y       z     NaN      NaN

你的情况是 dot 然后 split

out = df.dot(df.columns+',').str[:-1].str.split(',',expand=True).reindex(columns= np.arange(df.shape[1]))
Out[34]: 
       0  1     2   3
index                
1      w  y     z NaN
2      x  y  None NaN
3      y  z  None NaN