我在下面构建了一个数据框(df2),其中一些列名称的后缀格式为#/#。这些后缀中的第一个数字将与相应的" A"中的数字后缀相匹配。柱:
import pandas as pd
df1 = pd.DataFrame( { 'A': ['X', 'X1', 'X1', 'X2', 'X2', 'X2', 'X2', 'X3', 'X3' ],
'Property': [ 'p', 'p', 'p1/1', 'p', 'p2/1', 'p2/2', 'p2/3', 'p3/1', 'p3/2' ],
'Value': [ 'u', 'v', 'a', 't', 'a', 'b', 'c', 'a', 'b' ] } )
print df1
A Property Value
0 X p u
1 X1 p v
2 X1 p1/1 a
3 X2 p t
4 X2 p2/1 a
5 X2 p2/2 b
6 X2 p2/3 c
7 X3 p3/1 a
8 X3 p3/2 b
indices = [ col for col in df1.columns.tolist() if col != 'Value' ]
df2 = df1.set_index( indices )[ 'Value' ].unstack( 'Property' ).reset_index().fillna('-')
print df2
A p p1/1 p2/1 p2/2 p2/3 p3/1 p3/2
0 X u - - - - - -
1 X1 v a - - - - -
2 X2 t - a b c - -
3 X3 - - - - - a b
如何在df2上使用堆栈(或其他方法)来实现如下所示的数据帧,其中我通过添加新列x来浓缩一些信息,以识别原始#/#后缀中的第一个数字数据帧?
A p px/1 px/2 px/3 x
0 X u - - - -
1 X1 v a - - 1
2 X2 t a b c 2
3 X3 - a b - 3
注意,如果有一种方法可以直接从df1完成此操作,那对我的情况来说是最佳的,但是修改df2可能更多是其他人的常见用例。
答案 0 :(得分:3)
从头开始更改
df1.Property=('px/'+df1.Property.str.split('/',expand=True)[1]).fillna(df1.Property)
df2 = df1.set_index( indices )[ 'Value' ].unstack( 'Property' ).reset_index()
df2
Out[1360]:
Property A p px/1 px/2 px/3
0 X u None None None
1 X1 v a None None
2 X2 t a b c
3 X3 None a b None
答案 1 :(得分:3)
这必须是我曾经写过的最令人讨厌的事情
(
df.set_index(['A', 'p'])
.filter(regex='p\d+/\d+')
.mask(lambda d: d == '-', '')
.groupby(lambda x: x.split('/')[1], axis=1, )
.sum()
.mask(lambda d: d == '', '-')
.add_prefix('px/')
.reset_index()
.assign(x=lambda d: d.A.str.extract('(\d+)$', expand=False).fillna('-'))
)
A p px/1 px/2 px/3 x
0 X u - - - -
1 X1 v a - - 1
2 X2 t a b c 2
3 X3 - a b - 3
答案 2 :(得分:2)
首先创建列x然后创建groupby轴1和sum字符串
df.replace('-', '', inplace = True)
df['x'] = df.A.str.extract('(\d)', expand = False)
df = df.groupby(df.columns.str[-1], axis =1 ).sum().replace('', '-')
df.rename({'1' : 'px/1', '2' : 'px/2', '3' : 'px/3'}, axis = 1, inplace = True)
px/1 px/2 px/3 A p x
0 - - - X u 0.0
1 a - - X1 v 1.0
2 a b c X2 t 2.0
3 a b - X3 - 3.0