Pandas:如果列名相同,我想将它们堆叠在一起

fjnneemd  于 2022-12-17  发布在  其他
关注(0)|答案(3)|浏览(170)

我有一个表如下:
| 身份证|项目a| B|项目a| B|(c)秘书长的报告|颜色|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 一百二十三|1个|六个|七|三个|四个|蓝色|
| 四百五十六|第二章|八个|九|七|五个|黄色|
正如你所看到的,一些列有相同的。我想做的是堆叠列与相同的名称在对方的顶部(使表的长度比宽度)。我已经看了堆叠,融化和透视的文档,但我找不到一个类似的问题,因为我在这里。有人能告诉我如何才能实现这一点吗?
仅供参考,以下是我需要的表:
| 身份证|项目a| B|(c)秘书长的报告|颜色|
| - ------|- ------|- ------|- ------|- ------|
| 一百二十三|1个|六个|四个|蓝色|
| 一百二十三|七|三个|四个|蓝色|
| 四百五十六|第二章|八个|五个|黄色|
| 四百五十六|九|七|五个|黄色|

m528fe3b

m528fe3b1#

您可以使用groupby.cumcount进行重复数据消除,然后使用stackgroupby.ffill消除缺失值:

(df.set_axis(pd.MultiIndex.from_arrays([df.columns,
                                        df.groupby(level=0, axis=1).cumcount()
                                       ]), axis=1)
   .stack().groupby(level=0).ffill()
   .reset_index(drop=True).convert_dtypes() # optional
   [list(dict.fromkeys(df.columns))] # also optional, keep original order
)

输出:

id  a  b  c   color
0  123  1  6  4    blue
1  123  7  3  4    blue
2  456  2  8  5  yellow
3  456  9  7  5  yellow
yyyllmsg

yyyllmsg2#

# melt to turn wide to long format
df2=df.melt(id_vars=['id']) 

(df2.assign(seq=df2.groupby(['variable']).cumcount()) # assign a seq to create multiple rows for an id
 .pivot(index=['id','seq'], columns='variable', values='value' ) # pivot
 .reset_index()
 .drop(columns='seq')
 .rename_axis(columns=None)
).ffill()  # fill nan with previous value
id  a   b   c   color
0   123     1   6   4   blue
1   123     7   3   4   blue
2   456     2   8   5   yellow
3   456     9   7   5   yellow
2w2cym1i

2w2cym1i3#

一个选项是从pyjanitor使用pivot_longger;我添加了一个临时列c1,因此所有列的数量都是平衡的:

(df
.assign(c1=df.c)
.pivot_longer(
    index = ['id', 'color'], 
    names_to = '.value', 
    names_pattern = '(.)')
)
    id   color  a  b  c
0  123    blue  1  6  4
1  456  yellow  2  8  5
2  123    blue  7  3  4
3  456  yellow  9  7  5

相关问题