Python 将长数据帧转换为宽数据帧

Python 将长数据帧转换为宽数据帧,python,pandas,dataframe,Python,Pandas,Dataframe,系统化的方法是什么: x = {'col0': [1, 1, 2, 2], 'col1': ['a', 'b', 'a', 'b'], 'col2': ['x', 'x', 'x', 'x'], 'col3': [12, 13, 14, 15]} y = pd.DataFrame(data=x) y col0 col1 col2 col3 0 1 a x 12 1 1 b x 13 2 2 a x 14 3

系统化的方法是什么:

x = {'col0': [1, 1, 2, 2], 'col1': ['a', 'b', 'a', 'b'],
     'col2': ['x', 'x', 'x', 'x'], 'col3': [12, 13, 14, 15]}
y = pd.DataFrame(data=x)
y
   col0 col1 col2 col3
0    1     a    x   12
1    1     b    x   13
2    2     a    x   14
3    2     b    x   15
为此:

y2
   col0  col3__a_x  col3__b_x
0     1         12       13
1     2         14       15
我最初的想法是从R的重塑2软件包中选择
cast
。然而,与R相比,我对Pandas/Python不太熟悉


在我使用的数据集中,
col1
有3个不同的值,
col2
都是相同的值,~200000行,以及~80个其他可以添加后缀的列。

您需要
pviot
和column falten

s=pd.pivot_table(y,index='col0',columns=['col1','col2'],values='col3')
s.columns=s.columns.map('_'.join)
s.add_prefix('col3_').reset_index()
Out[1383]: 
   col0  col3_a_x  col3_b_x
0     1        12        13
1     2        14        15

我认为@Wen的解决方案可能更好,因为它是纯
pandas
,但如果您想使用
numpy
,这里有另一个解决方案:

import numpy as np

d = y.groupby('col0').apply(lambda x: x['col3']).unstack().values
d = d[~np.isnan(d)].reshape(len(d),-1)
new_df = pd.DataFrame(d).reset_index().rename(columns={'index': 'col0', 0: 'col3_a_x', 1:'col3_b_x'})

>>> new_df
   col0  col3_a_x  col3_b_x
0     0      12.0      13.0
1     1      14.0      15.0

如果结果行和列没有多个值,则可以使用
set_index
unstack
执行此操作,否则必须使用聚合方法,如pivot_table或groupby:

df_out = y.set_index(['col0','col1','col2']).unstack([1,2])
df_out.columns = df_out.columns.map('_'.join)
df_out.reset_index()
输出:

   col0  col3_a_x  col3_b_x
0     1        12        13
1     2        14        15
或使用groupby使用多个值:

df_out = y.groupby(['col0','col1','col2']).mean().unstack([1,2])
df_out.columns = df_out.columns.map('_'.join)
df_out.reset_index()

使用
pd.factorize
和Numpy slice赋值,我们可以构造我们需要的数据帧

i, r = pd.factorize(df.col0)
j, c = pd.factorize(df.col1.str.cat(df.col2, '_'))
b = np.zeros((r.size, c.size), np.int64)
b[i, j] = df.col3.values

d = pd.DataFrame(
    np.column_stack([r, b]),
    columns=['col0'] + ['col3__' + col for col in c]
)

d

   col0  col3__a_x  col3__b_x
0     1         12         13
1     2         14         15

谢谢你,我想我已经成功了。不过,我有一个跟进问题。此解决方案仅适用于
col3
,对于
col3 col4 col5有没有办法做到这一点。。。col10
一次完成所有操作?如果需要,我可以做某种循环。@ChaseGrimm您可以更改try
s=y.set_index(['col0','col1','col2'])。取消堆栈(level=[1,2]);s、 columns=s.columns.map('''.join)
谢谢,我使用了
s=pd.pivot_表(df,index=['Periods','factor'],columns=['decile','function'],values=list(df)[4:])