Python 3.x 将数据转换为列
我有一个熊猫数据框,看起来像这样:Python 3.x 将数据转换为列,python-3.x,pandas,Python 3.x,Pandas,我有一个熊猫数据框,看起来像这样: | | x_id | x_name | has_policy | payment_name | count | |---|------|--------|------------|--------------|-------| | 0 | 2 | two | 0 | Hybrid | 58 | | 1 | 2 | two | 1 | Hybrid | 2 |
| | x_id | x_name | has_policy | payment_name | count |
|---|------|--------|------------|--------------|-------|
| 0 | 2 | two | 0 | Hybrid | 58 |
| 1 | 2 | two | 1 | Hybrid | 2 |
| 2 | 5 | five | 1 | Excl | 13 |
| 3 | 5 | five | 0 | Excl | 70 |
| 4 | 5 | five | 0 | Agen | 811 |
| 5 | 5 | five | 1 | Agen | 279 |
| 6 | 5 | five | 1 | Hybrid | 600 |
| 7 | 5 | five | 0 | Hybrid | 2819 |
| id | name | no_policy_hybrid | no_policy_excl | no_policy_agen | policy_hybrid | policy_excl | policy_agen |
|----|------|------------------|----------------|----------------|---------------|-------------|-------------|
| 2 | two | 58 | 0 | 0 | 2 | 0 | 0 |
| 5 | five | 2819 | 70 | 811 | 600 | 13 | 279 |
我希望将has_policy
和payment_name
组合成一列,分别包含计数
。预期输出如下所示:
| | x_id | x_name | has_policy | payment_name | count |
|---|------|--------|------------|--------------|-------|
| 0 | 2 | two | 0 | Hybrid | 58 |
| 1 | 2 | two | 1 | Hybrid | 2 |
| 2 | 5 | five | 1 | Excl | 13 |
| 3 | 5 | five | 0 | Excl | 70 |
| 4 | 5 | five | 0 | Agen | 811 |
| 5 | 5 | five | 1 | Agen | 279 |
| 6 | 5 | five | 1 | Hybrid | 600 |
| 7 | 5 | five | 0 | Hybrid | 2819 |
| id | name | no_policy_hybrid | no_policy_excl | no_policy_agen | policy_hybrid | policy_excl | policy_agen |
|----|------|------------------|----------------|----------------|---------------|-------------|-------------|
| 2 | two | 58 | 0 | 0 | 2 | 0 | 0 |
| 5 | five | 2819 | 70 | 811 | 600 | 13 | 279 |
我正在查看和的文档,我不确定哪一个是最好的,尽管我觉得转置对于这个用例来说更有意义,因为计数列已经是一个聚合了。第一个想法是通过和旋转,排序多索引和展平:
df['has_policy'] = df['has_policy'].map({0:'no_policy', 1:'policy'})
df = df.set_index(['x_id','x_name','has_policy','payment_name'])['count'].unstack([2,3], fill_value=0).sort_index(axis=1, level=0)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
df = df.reset_index()
print (df)
x_id x_name no_policy_Agen no_policy_Excl no_policy_Hybrid policy_Agen \
0 2 two 0 0 58 0
1 5 five 811 70 2819 279
policy_Excl policy_Hybrid
0 0 2
1 13 600
如有必要,另一个想法是将和
相加:
df['has_policy'] = df['has_policy'].map({0:'no_policy', 1:'policy'})
df = df.pivot_table(index=['x_id','x_name'],
columns=['has_policy','payment_name'],
values='count',
aggfunc='sum',
fill_value=0).sort_index(axis=1, level=0)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
df = df.reset_index()
print (df)
x_id x_name no_policy_Agen no_policy_Excl no_policy_Hybrid policy_Agen \
0 2 two 0 0 58 0
1 5 five 811 70 2819 279
policy_Excl policy_Hybrid
0 0 2
1 13 600
第一个想法是通过and旋转,排序多索引
并展平:
df['has_policy'] = df['has_policy'].map({0:'no_policy', 1:'policy'})
df = df.set_index(['x_id','x_name','has_policy','payment_name'])['count'].unstack([2,3], fill_value=0).sort_index(axis=1, level=0)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
df = df.reset_index()
print (df)
x_id x_name no_policy_Agen no_policy_Excl no_policy_Hybrid policy_Agen \
0 2 two 0 0 58 0
1 5 five 811 70 2819 279
policy_Excl policy_Hybrid
0 0 2
1 13 600
如有必要,另一个想法是将和相加:
df['has_policy'] = df['has_policy'].map({0:'no_policy', 1:'policy'})
df = df.pivot_table(index=['x_id','x_name'],
columns=['has_policy','payment_name'],
values='count',
aggfunc='sum',
fill_value=0).sort_index(axis=1, level=0)
df.columns = df.columns.map(lambda x: f'{x[0]}_{x[1]}')
df = df.reset_index()
print (df)
x_id x_name no_policy_Agen no_policy_Excl no_policy_Hybrid policy_Agen \
0 2 two 0 0 58 0
1 5 five 811 70 2819 279
policy_Excl policy_Hybrid
0 0 2
1 13 600
您可以使用、使用和展平多索引列:
您可以使用、使用和展平多索引列:
你可以试试这样的
grouped = df.groupby(('x_name', 'x_id', 'has_policy', 'payment_name'))
counts = grouped['count'].sum().reset_index()
counts
x_name x_id has_policy payment_name count
0 five 5 0 Agen 811
1 five 5 0 Excl 70
2 five 5 0 Hybrid 2819
3 five 5 1 Agen 279
4 five 5 1 Excl 13
5 five 5 1 Hybrid 600
6 two 2 0 Hybrid 58
7 two 2 1 Hybrid 2
counts['policy_payment'] = counts['has_policy'].map({0 : 'no_policy', 1: 'policy'}) \
+ '_' \
+ counts['payment_name'].map(lambda s: s.lower())
table = counts.pivot(index='x_name', columns='policy_payment', values='count').fillna(0)
table
policy_payment no_policy_agen no_policy_excl no_policy_hybrid policy_agen policy_excl policy_hybrid
x_name
five 811.0 70.0 2819.0 279.0 13.0 600.0
two 0.0 0.0 58.0 0.0 0.0 2.0
在pandas 1.1.0中,您应该能够在
pd.DataFrame.pivot
中设置index=[x\u id,x\u name]
,以获得所描述的内容。您可以尝试类似的方法
grouped = df.groupby(('x_name', 'x_id', 'has_policy', 'payment_name'))
counts = grouped['count'].sum().reset_index()
counts
x_name x_id has_policy payment_name count
0 five 5 0 Agen 811
1 five 5 0 Excl 70
2 five 5 0 Hybrid 2819
3 five 5 1 Agen 279
4 five 5 1 Excl 13
5 five 5 1 Hybrid 600
6 two 2 0 Hybrid 58
7 two 2 1 Hybrid 2
counts['policy_payment'] = counts['has_policy'].map({0 : 'no_policy', 1: 'policy'}) \
+ '_' \
+ counts['payment_name'].map(lambda s: s.lower())
table = counts.pivot(index='x_name', columns='policy_payment', values='count').fillna(0)
table
policy_payment no_policy_agen no_policy_excl no_policy_hybrid policy_agen policy_excl policy_hybrid
x_name
five 811.0 70.0 2819.0 279.0 13.0 600.0
two 0.0 0.0 58.0 0.0 0.0 2.0
在pandas 1.1.0中,您应该能够在
pd.DataFrame.pivot
中设置index=[x\u id,x\u name]
,以获得您所描述的内容。第一个解决方案非常有效。最后我得到了一列no\u policy\u nan
,但每一行都是0,所以我可以直接删除它。另外,快速跟进问题。我如何在这里向索引中添加更多列?例如,如果原始数据框中有另一列country
,是否只需将其放入set_index()
,可能在x_name
之后?第一个解决方案非常有效。最后我得到了一列no\u policy\u nan
,但每一行都是0,所以我可以直接删除它。另外,快速跟进问题。我如何在这里向索引中添加更多列?例如,如果原始数据框中有另一列country
,是否只将其放在set_index()
,可能在x_name
之后?