pandas长时间地重新整形

我有长格式的数据,正在尝试重新整形,但似乎没有一个简单的方法来使用熔体/堆栈/叠加来做到这一点:

Salesman Height product price Knut 6 bat 5 Knut 6 ball 1 Knut 6 wand 3 Steve 5 pen 2 

变为:

 Salesman Height product_1 price_1 product_2 price_2 product_3 price_3 Knut 6 bat 5 ball 1 wand 3 Steve 5 pen 2 NA NA NA NA 

我觉得Stata可以用重塑命令做这样的事情。

一个简单的支点可能已经足够满足您的需求,但这是我做的重现您所需的输出:

 df['idx'] = df.groupby('Salesman').cumcount() 

只要添加一个组内的计数器/索引,就可以使您获得大部分的信息,但列标签不会像您所期望的那样:

 print df.pivot(index='Salesman',columns='idx')[['product','price']] product price idx 0 1 2 0 1 2 Salesman Knut bat ball wand 5 1 3 Steve pen NaN NaN 2 NaN NaN 

为了更接近你想要的输出,我添加了以下内容:

 df['prod_idx'] = 'product_' + df.idx.astype(str) df['prc_idx'] = 'price_' + df.idx.astype(str) product = df.pivot(index='Salesman',columns='prod_idx',values='product') prc = df.pivot(index='Salesman',columns='prc_idx',values='price') reshape = pd.concat([product,prc],axis=1) reshape['Height'] = df.set_index('Salesman')['Height'].drop_duplicates() print reshape product_0 product_1 product_2 price_0 price_1 price_2 Height Salesman Knut bat ball wand 5 1 3 6 Steve pen NaN NaN 2 NaN NaN 5 

编辑:如果你想泛化程序更多的variables,我认为你可以做下面的事情(虽然它可能不够高效):

 df['idx'] = df.groupby('Salesman').cumcount() tmp = [] for var in ['product','price']: df['tmp_idx'] = var + '_' + df.idx.astype(str) tmp.append(df.pivot(index='Salesman',columns='tmp_idx',values=var)) reshape = pd.concat(tmp,axis=1) 

@鲁克说:

我觉得Stata可以用重塑命令做这样的事情。

你可以,但我想你也需要一个组内的计数器来获得stata中的重塑来获得你想要的输出:

  +-------------------------------------------+ | salesman idx height product price | |-------------------------------------------| 1. | Knut 0 6 bat 5 | 2. | Knut 1 6 ball 1 | 3. | Knut 2 6 wand 3 | 4. | Steve 0 5 pen 2 | +-------------------------------------------+ 

如果你添加idx那么你可以在stata进行重塑:

 reshape wide product price, i(salesman) j(idx) 

有点老,但我会张贴给其他人。

你想要什么都可以实现,但是你可能不需要它;)Pandas支持行和列的分层索引。 在Python 2.7.x中…

 from StringIO import StringIO raw = '''Salesman Height product price Knut 6 bat 5 Knut 6 ball 1 Knut 6 wand 3 Steve 5 pen 2''' dff = pd.read_csv(StringIO(raw), sep='\s+') print dff.set_index(['Salesman', 'Height', 'product']).unstack('product') 

产生一个比你想要的更方便的表示

  price product ball bat pen wand Salesman Height Knut 6 1 5 NaN 3 Steve 5 NaN NaN 2 NaN 

使用set_index和destacking与单个函数作为pivot的优点是,您可以将操作分解为简单的小步骤,从而简化了debugging过程。

 pivoted = df.pivot('salesman', 'product', 'price') 

皮克。 192用于数据分析的Python

这是另外一个解决scheme,从Chris Albon的网站取得更丰富的内容 。

创build“长”数据框

 raw_data = {'patient': [1, 1, 1, 2, 2], 'obs': [1, 2, 3, 1, 2], 'treatment': [0, 1, 0, 1, 0], 'score': [6252, 24243, 2345, 2342, 23525]} df = pd.DataFrame(raw_data, columns = ['patient', 'obs', 'treatment', 'score']) 

制作一个“宽”的数据

 df.pivot(index='patient', columns='obs', values='score') 

重塑文档在这里

您正在寻找pd.wide_to_long() (这是stata命令的直接模拟)