我有这两张表:
T1
id x y
8 42 1.9
9 30 1.9
T2
id signal
8 55
8 56
8 59
9 57
9 58
9 60
目标是获取新表T3:
id x y s1 s2 s3
8 42 1.9 55 56 58
9 30 1.9 57 58 60
如果我做这个操作,那么它只进行合并而不进行转置:
pd.merge(T1, T2, on=['id'])
如何创建列s1
、s2
和s3
,每列对应一行(每个id<的行数
总是固定的并且等于 3)?
最佳答案
更新:
正如@Jeff 在他的评论中所写,@ubuntu 的解决方案与我的相比应该更快、更惯用:
In [40]: T1.merge(
....: T2.pivot_table(index='id',
....: values='signal',
....: columns='s' + T2.groupby(['id'])['signal'].cumcount().astype(str))
....: .reset_index()
....: )
Out[40]:
id x y s0 s1 s2
0 8 42 1.9 55 56 59
1 9 30 1.9 57 58 60
旧答案:
你可以这样做:
In [209]: %paste
(t1.set_index('id')
.join(t2.groupby('id')['signal']
.apply(lambda x: x.tolist())
.apply(pd.Series))
.reset_index()
)
## -- End pasted text --
Out[209]:
id x y 0 1 2
0 8 42 1.9 55 56 59
1 9 30 1.9 57 58 60
解释:
按id
对T2
进行分组,并将所有相应的信号“收集”到列表中
In [211]: t2.groupby('id')['signal'].apply(lambda x: x.tolist())
Out[211]:
id
8 [55, 56, 59]
9 [57, 58, 60]
Name: signal, dtype: object
将列表扩展到列
In [213]: t2.groupby('id')['signal'].apply(lambda x: x.tolist()).apply(pd.Series)
Out[213]:
0 1 2
id
8 55 56 59
9 57 58 60
最后通过索引 id
连接两个表
PS 如果你想重命名所有数字列,你可以这样做(假设你将结果保存到 rslt
DF 中):
In [224]: rslt.columns = [c if c in ['id','x','y'] else 's{}'.format(c) for c in rslt.columns.tolist()]
In [225]: rslt
Out[225]:
id x y s0 s1 s2
0 8 42 1.9 55 56 59
1 9 30 1.9 57 58 60
关于python - 如何合并两个表并将行转置为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37787289/