从这个系统的方法是什么:
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的reshape2包中考虑类似cast
的内容。但是,我对Pandas / Python的熟悉程度远远低于我对R的熟悉程度。
在我使用col1
的数据集中有3个不同的值,col2
是相同的值,~200,000行,以及〜80个其他列,可以添加后缀。
答案 0 :(得分:4)
您需要pviot
和列faltten
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
答案 1 :(得分:3)
如果没有结果行和列的多个值,则可以使用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()
答案 2 :(得分:3)
使用pd.factorize
和Numpy切片分配,我们可以构建我们需要的数据框。
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
答案 3 :(得分:2)
我认为@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