我有一个具有以下结构的 Pandas 数据框:
A B C
a b 1
a b 2
a b 3
c d 7
c d 8
c d 5
c d 6
c d 3
e b 4
e b 3
e b 2
e b 1
Run Code Online (Sandbox Code Playgroud)
我想把它改成这样:
A B C1 C2 C3 C4 C5
a b 1 2 3 NAN NAN
c d 7 8 5 6 3
e b 4 3 2 1 NAN
Run Code Online (Sandbox Code Playgroud)
换句话说,类似于对 A 和 B 进行分组并将 C 扩展到不同的列。
知道每组的长度是不同的。
C已经订购了
较短的组可以有 NAN 或 NULL 值(空),这并不重要。
jez*_*ael 12
使用GroupBy.cumcount
and 和pandas.Series.add
1, 从 1 开始命名新列,然后将其传递给DataFrame.pivot
, 并添加DataFrame.add_prefix
以重命名列(C1、C2、C3 等...)。最后用于DataFrame.rename_axis
删除索引原始名称('g')并MultiIndex
使用DataFrame.reset_index
columns将其转换为列A,B
:
df['g'] = df.groupby(['A','B']).cumcount().add(1)
df = df.pivot(['A','B'], 'g', 'C').add_prefix('C').rename_axis(columns=None).reset_index()
print (df)
A B C1 C2 C3 C4 C5
0 a b 1.0 2.0 3.0 NaN NaN
1 c d 7.0 8.0 5.0 6.0 3.0
2 e b 4.0 3.0 2.0 1.0 NaN
Run Code Online (Sandbox Code Playgroud)
因为NaN
默认情况下是 float 类型,如果您需要列 dtype 为整数,请DataFrame.astype
添加Int64
:
df['g'] = df.groupby(['A','B']).cumcount().add(1)
df = (df.pivot(['A','B'], 'g', 'C')
.add_prefix('C')
.astype('Int64')
.rename_axis(columns=None)
.reset_index())
print (df)
A B C1 C2 C3 C4 C5
0 a b 1 2 3 <NA> <NA>
1 c d 7 8 5 6 3
2 e b 4 3 2 1 <NA>
Run Code Online (Sandbox Code Playgroud)
编辑:如果要添加的新列数量达到上限N
,则意味着它们A,B
是重复的。因此,需要添加g1, g2
具有整数和模除法的辅助组,在索引中添加一个新级别:
N = 4
g = df.groupby(['A','B']).cumcount()
df['g1'], df['g2'] = g // N, (g % N) + 1
df = (df.pivot(['A','B','g1'], 'g2', 'C')
.add_prefix('C')
.droplevel(-1)
.rename_axis(columns=None)
.reset_index())
print (df)
A B C1 C2 C3 C4
0 a b 1.0 2.0 3.0 NaN
1 c d 7.0 8.0 5.0 6.0
2 c d 3.0 NaN NaN NaN
3 e b 4.0 3.0 2.0 1.0
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1043 次 |
最近记录: |