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
之后?