Python 将pandas中的列值复制到非零单元格,并在其后聚合列

Python 将pandas中的列值复制到非零单元格,并在其后聚合列,python,pandas,dataframe,Python,Pandas,Dataframe,我有这样的数据框 Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4 0 A B C A D D A 1 B A C C B A 2 C D 我想把它转换成 Index P1 P2

我有这样的数据框

Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
  0    A          B   C          A    D    D    A    
  1    B          A              C    C    B         A
  2               C   D          
我想把它转换成

Index    P1         P2         P3
  0      A(P1W1)    A(P2W2)    A(P3W1)
  1      A(P1W3)    B(P2W4)    A(P3W2)
  2      B(P1W1)    C(P2W2)
  3      B(P1W3)    C(P2W3)
  4      C(P1W3)    D(P2W3)
  5      C(P1W4)    D(P2W4)
  6      D(P1W4)
基本上,我想从第一个数据帧中获取包含单元格值的列名,然后在p1p2级别对其进行聚合

如果需要任何澄清,请询问


我完全不知道如何进行此操作,如有任何帮助,将不胜感激

设置

txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
  0    A          B   C          A    D    D    A    
  1    B          A              C    C    B         A
  2               C   D            """

df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df

      P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index                                                            
0        A         B    C         A    D    D    A               
1        B         A              C    C    B         A          
2                  C    D                                        
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
    g: d.stack().reset_index(drop=True)
    for g, d in d.where(df.astype(bool)).groupby(
        lambda col: col[:2], 1
    )
}, axis=1).fillna('')

        P1       P2       P3
0  A(P1W1)  A(P2W2)  A(P3W1)
1  B(P1W3)  D(P2W3)  A(P3W2)
2  C(P1W4)  D(P2W4)         
3  B(P1W1)  C(P2W2)         
4  A(P1W3)  C(P2W3)         
5  C(P1W3)  B(P2W4)         
6  D(P1W4)                 

解决方案

txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
  0    A          B   C          A    D    D    A    
  1    B          A              C    C    B         A
  2               C   D            """

df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df

      P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index                                                            
0        A         B    C         A    D    D    A               
1        B         A              C    C    B         A          
2                  C    D                                        
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
    g: d.stack().reset_index(drop=True)
    for g, d in d.where(df.astype(bool)).groupby(
        lambda col: col[:2], 1
    )
}, axis=1).fillna('')

        P1       P2       P3
0  A(P1W1)  A(P2W2)  A(P3W1)
1  B(P1W3)  D(P2W3)  A(P3W2)
2  C(P1W4)  D(P2W4)         
3  B(P1W1)  C(P2W2)         
4  A(P1W3)  C(P2W3)         
5  C(P1W3)  B(P2W4)         
6  D(P1W4)                 

详细信息

txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
  0    A          B   C          A    D    D    A    
  1    B          A              C    C    B         A
  2               C   D            """

df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df

      P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index                                                            
0        A         B    C         A    D    D    A               
1        B         A              C    C    B         A          
2                  C    D                                        
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
    g: d.stack().reset_index(drop=True)
    for g, d in d.where(df.astype(bool)).groupby(
        lambda col: col[:2], 1
    )
}, axis=1).fillna('')

        P1       P2       P3
0  A(P1W1)  A(P2W2)  A(P3W1)
1  B(P1W3)  D(P2W3)  A(P3W2)
2  C(P1W4)  D(P2W4)         
3  B(P1W1)  C(P2W2)         
4  A(P1W3)  C(P2W3)         
5  C(P1W3)  B(P2W4)         
6  D(P1W4)                 
添加用括号括起来的列

df + df.columns.map(lambda c: f'({c})')

          P1W1    P1W2     P1W3     P1W4    P2W1     P2W2     P2W3     P2W4     P3W1     P3W2    P3W3    P3W4
Index                                                                                                        
0      A(P1W1)  (P1W2)  B(P1W3)  C(P1W4)  (P2W1)  A(P2W2)  D(P2W3)  D(P2W4)  A(P3W1)   (P3W2)  (P3W3)  (P3W4)
1      B(P1W1)  (P1W2)  A(P1W3)   (P1W4)  (P2W1)  C(P2W2)  C(P2W3)  B(P2W4)   (P3W1)  A(P3W2)  (P3W3)  (P3W4)
2       (P1W1)  (P1W2)  C(P1W3)  D(P1W4)  (P2W1)   (P2W2)   (P2W3)   (P2W4)   (P3W1)   (P3W2)  (P3W3)  (P3W4)
使用遮罩在适当的位置制作
NaN
。这将使我们能够在理解范围内进行叠加,并为方便起见,删除
NaN

d = df + df.columns.map(lambda c: f'({c})')
d.where(df.astype(bool))

          P1W1 P1W2     P1W3     P1W4 P2W1     P2W2     P2W3     P2W4     P3W1     P3W2 P3W3 P3W4
Index                                                                                            
0      A(P1W1)  NaN  B(P1W3)  C(P1W4)  NaN  A(P2W2)  D(P2W3)  D(P2W4)  A(P3W1)      NaN  NaN  NaN
1      B(P1W1)  NaN  A(P1W3)      NaN  NaN  C(P2W2)  C(P2W3)  B(P2W4)      NaN  A(P3W2)  NaN  NaN
2          NaN  NaN  C(P1W3)  D(P1W4)  NaN      NaN      NaN      NaN      NaN      NaN  NaN  NaN

通过应用于我们选择的索引对象的
lambda
进行分组。我们将选择axis=1来定位列。

这很聪明!问题是,从P10W1开始,所有的都在P1之下。因此,我们有没有办法不把P10和P1I弄错?通过考虑3个字母(P1W)而不是P1,然后将P1W重命名为P1