当前位置: 首页 > 知识库问答 >
问题:

Python Pandas在不聚合的情况下透视包含重复值的多个字符串列

狄兴业
2023-03-14

我有以下数据框架,并希望以这样的方式进行数据透视:将列< code>Imprv_Attribute转换为每个键的单个列,并且值应为< code>Imprv_Attr_Desc。我还需要< code>Imprv_Attr_Units信息,对于每个新创建的列,例如< code >浴室的< code>Imprv_Attr_Units应该有自己的名为< code >浴室_Imprv_Attr_Units的列。

|     | Parcel        | Imprv_Attribute | Imprv_Attr_Desc   | Imprv_Attr_Units |
| --- | ------------- | --------------- | ----------------- | ---------------- |
| 0   | 00002-000-000 | Bathrooms       | 2.0-Baths         | 1.0              |
| 1   | 00002-000-000 | Bedrooms        | 2-2 BEDROOMS      | 1.0              |
| 2   | 00002-000-000 | Exterior Wall   | 13-PRE-FAB PANEL  | 100.0            |
| 3   | 00002-000-000 | Floor Cov       | 08-SHEET VINYL    | 20.0             |
| 4   | 00002-000-000 | Floor Cov       | 14-CARPET         | 80.0             |
| 5   | 00011-000-000 | Bathrooms       | 3.0-Baths         | 1.0              |
| 6   | 00011-000-000 | Bedrooms        | 3-3 BEDROOMS      | 1.0              |
| 7   | 00011-000-000 | Exterior Wall   | 15-CONCRETE BLOCK | 60.0             |
| 8   | 00011-000-000 | Exterior Wall   | 20-FACE BRICK     | 40.0             |
| 9   | 00011-000-000 | Floor Cov       | 14-CARPET         | 100.0            |

我的最终结果应该是这样的:

| Parcel        | Bathrooms | Bathrooms_Imprv_Attr_Units | Bedrooms     | Bedrooms_Imprv_Attr_Units | Exterior Wall     | Exterior Wall_Imprv_Attr_Units | Floor Cov      | Floor Cov_Imprv_Attr_Unit |
| ------------- | --------- | -------------------------- | ------------ | ------------------------- | ----------------- | ------------------------------ | -------------- | ------------------------- |
| 00002-000-000 | 2.0-Baths | 1.0                        | 2-2 BEDROOMS | 1.0                       | 13-PRE-FAB PANEL  | 100.0                          | 08-SHEET VINYL | 20.0                      |
| 00002-000-000 |           |                            |              |                           |                   |                                | 14-CARPET      | 80.0                      |
| 00011-000-000 | 3.0-Baths | 1.0                        | 3-3 BEDROOMS | 1.0                       | 15-CONCRETE BLOCK | 60.0                           | 14-CARPET      | 100.0                     |
| 00011-000-000 |           |                            |              |                           | 20-FACE BRICK     | 40.0                           |                |                           |

到目前为止,我已经试过了:

from io import StringIO
import pandas as pd

data = StringIO(
    """
Parcel;Imprv_Attribute;Imprv_Attr_Desc;Imprv_Attr_Units
00002-000-000;Bathrooms;2.0-Baths;1.0
00002-000-000;Bedrooms; 2-2 BEDROOMS;1.0
00002-000-000;Exterior Wall;13-PRE-FAB PANEL;100.0
00002-000-000;Floor Cov;08-SHEET VINYL;   20.0
00002-000-000;Floor Cov;14-CARPET;80.0
00011-000-000;Bathrooms;3.0-Baths;1.0
00011-000-000;Bedrooms; 3-3 BEDROOMS;1.0
00011-000-000;Exterior Wall;15-CONCRETE BLOCK;60.0
00011-000-000;Exterior Wall;20-FACE BRICK;40.0
00011-000-000;Floor Cov;14-CARPET;100.0
"""
)
df = pd.read_csv(data, sep=";")
df = df.pivot_table(values="Imprv_Attr_Desc", index="Parcel", columns="Imprv_Attribute", aggfunc="first")
print(df)

这导致了此数据帧,其中由于聚合函数< code>first,我丢失了有关< code >地板覆盖层和< code >外墙的信息。

| Parcel        | Bathrooms | Bedrooms     | Exterior Wall     | Floor Cov      |
| ------------- | --------- | ------------ | ----------------- | -------------- |
| 00002-000-000 | 2.0-Baths | 2-2 BEDROOMS | 13-PRE-FAB PANEL  | 08-SHEET VINYL |
| 00011-000-000 | 3.0-Baths | 3-3 BEDROOMS | 15-CONCRETE BLOCK | 14-CARPET      |

我也试过这个答案

df = df.pivot_table(index=[df.index, "Parcel"], columns="Imprv_Attribute", values="Imprv_Attr_Desc")
print(df)

这导致熊猫.core.base.DataEror:没有要聚合的数值类型。我也尝试过分组,但这也没有达到我想要的结果:

df_group = df.groupby(["Parcel"])
for key, item in df_group:
    df = df_group.get_group(key)
    df = df.pivot(columns="Imprv_Attribute", values="Imprv_Attr_Desc")
    print(df, "\n\n")
<class 'pandas.core.frame.DataFrame'>
Imprv_Attribute  Bathrooms      Bedrooms     Exterior Wall       Floor Cov           HC&V     HVAC  Heat System Interior Wall  Num Res Units     Roof Type     Roofing
0                2.0-Baths           NaN               NaN             NaN            NaN      NaN          NaN           NaN            NaN           NaN         NaN
1                      NaN  2-2 BEDROOMS               NaN             NaN            NaN      NaN          NaN           NaN            NaN           NaN         NaN
2                      NaN           NaN  13-PRE-FAB PANEL             NaN            NaN      NaN          NaN           NaN            NaN           NaN         NaN
3                      NaN           NaN               NaN  08-SHEET VINYL            NaN      NaN          NaN           NaN            NaN           NaN         NaN
4                      NaN           NaN               NaN       14-CARPET            NaN      NaN          NaN           NaN            NaN           NaN         NaN
5                      NaN           NaN               NaN             NaN  04-FORCED AIR      NaN          NaN           NaN            NaN           NaN         NaN
6                      NaN           NaN               NaN             NaN            NaN      NaN  04-ELECTRIC           NaN            NaN           NaN         NaN
7                      NaN           NaN               NaN             NaN            NaN  01-NONE          NaN           NaN            NaN           NaN         NaN
8                      NaN           NaN               NaN             NaN            NaN      NaN          NaN      04-PANEL            NaN           NaN         NaN
9                      NaN           NaN               NaN             NaN            NaN      NaN          NaN           NaN  Num Res Units           NaN         NaN
10                     NaN           NaN               NaN             NaN            NaN      NaN          NaN           NaN            NaN  03-GABLE/HIP         NaN
11                     NaN           NaN               NaN             NaN            NaN      NaN          NaN           NaN            NaN           NaN  03-ASPHALT

<class 'pandas.core.frame.DataFrame'>
Imprv_Attribute  Bathrooms      Bedrooms      Exterior Wall  Floor Cov           HC&V        HVAC  Heat System Interior Wall  Num Res Units     Roof Type     Roofing
12               3.0-Baths           NaN                NaN        NaN            NaN         NaN          NaN           NaN            NaN           NaN         NaN
13                     NaN  3-3 BEDROOMS                NaN        NaN            NaN         NaN          NaN           NaN            NaN           NaN         NaN
14                     NaN           NaN  15-CONCRETE BLOCK        NaN            NaN         NaN          NaN           NaN            NaN           NaN         NaN
15                     NaN           NaN      20-FACE BRICK        NaN            NaN         NaN          NaN           NaN            NaN           NaN         NaN
16                     NaN           NaN                NaN  14-CARPET            NaN         NaN          NaN           NaN            NaN           NaN         NaN
17                     NaN           NaN                NaN        NaN  04-FORCED AIR         NaN          NaN           NaN            NaN           NaN         NaN
18                     NaN           NaN                NaN        NaN            NaN         NaN  04-ELECTRIC           NaN            NaN           NaN         NaN
19                     NaN           NaN                NaN        NaN            NaN  03-CENTRAL          NaN           NaN            NaN           NaN         NaN
20                     NaN           NaN                NaN        NaN            NaN         NaN          NaN    05-DRYWALL            NaN           NaN         NaN

根据这个答案,解决方案可能是< code>pd的组合。DataFrame.groupby和< code>pd。DataFrame.unstack,但目前我不知道如何将这些应用到我的案例中。

如果任何人有一个如何帮助我的好主意,我将非常感谢。

共有1个答案

须彭亮
2023-03-14

这可以通过pivot_table(类似于如何透视规范中的问题10)和一些额外的步骤来完成。

首先,您需要创建一个< code>cumcount级别,以便每个< code>'Parcel'中的重复' < code>Imprv_Attribute'值获得自己的标签,您可以使用该标签指定索引。然后聚合多个值列(首先是< code > )。通过在简单的列表理解中强加您的命名约定,我们将在折叠的列上留下一个多索引。最后,我们可以对列进行排序,并删除我们创建的索引的< code>cumcount级别。

df['N'] = df.groupby(['Parcel', 'Imprv_Attribute']).cumcount()

df1 = df.pivot_table(index=['Parcel', 'N'], 
                     columns='Imprv_Attribute', 
                     values=['Imprv_Attr_Desc', 'Imprv_Attr_Units'],
                     aggfunc='first')

df1.columns = [x[1] if x[0] == 'Imprv_Attr_Desc' else '_'.join(x[::-1]) for x in df1.columns]
df1 = df1.sort_index(axis=1).reset_index().drop(columns='N')
          Parcel  Bathrooms  Bathrooms_Imprv_Attr_Units      Bedrooms  Bedrooms_Imprv_Attr_Units      Exterior Wall  Exterior Wall_Imprv_Attr_Units       Floor Cov  Floor Cov_Imprv_Attr_Units
0  00002-000-000  2.0-Baths                         1.0  2-2 BEDROOMS                        1.0   13-PRE-FAB PANEL                           100.0  08-SHEET VINYL                        20.0
1  00002-000-000        NaN                         NaN           NaN                        NaN                NaN                             NaN       14-CARPET                        80.0
2  00011-000-000  3.0-Baths                         1.0  3-3 BEDROOMS                        1.0  15-CONCRETE BLOCK                            60.0       14-CARPET                       100.0
3  00011-000-000        NaN                         NaN           NaN                        NaN      20-FACE BRICK                            40.0             NaN                         NaN
 类似资料: