pandas pivot 或 groupby 多列和控制列

Posted

技术标签:

【中文标题】pandas pivot 或 groupby 多列和控制列【英文标题】:pandas pivot or groupby multiple columns and control columns 【发布时间】:2021-05-30 08:43:10 【问题描述】:

需要修改以下df

gears   milesbefore milesafter  model_car   safety_car  gears   milesbefore milesafter  model_truck safety_truck
1       10          20          honda       NTSB        5       100         200         volvo       NTSB
1       10          20          honda       NTFD        5       100         200         volvo       NTFD
1       10          20          honda       NRTB        5       100         200         volvo       NRTB
1       10          20          toyota      NTFD        5       100         200         merc        NTFD
1       10          20          toyota      NTFD        5       100         200         merc        NTFD
1       10          20          toyota      NRTB        5       100         200         merc        NRTB
1       10          20          jeep        NTSB        5       100         200         jaguar      NTSB
1       10          20          jeep        NTFD        5       100         200         jaguar      NTFD
1       10          20          jeep        NRTB        5       100         200         jaguar      NRTB
1       10          20          jeep        NRTB        6       1000        2000        jaguar      NTFB

到这里

model_car   model_truck NTSB_car    NTFD_car    NRTB_car    NTSB_truck  NTFD_truck  NRTB_truck
honda       volvo       1:10:20     1:10:20     1:10:20     5:100:200   5:100:200   5:100:200
toyota      merc        1:10:20     1:10:20     1:10:20     5:100:200   5:100:200   5:100:200
jeep        jaguar      1:10:20     1:10:20     1:10:20     5:100:200   5:100:200   5:100:200

这涉及三个条件 一组由 model_car 和 safety_car 二是避免看起来像这样的行

1   10  20  jeep    NRTB    6   1000    2000    jaguar  NTFB

安全监控机构不匹配的地方。理想情况下,我会活着将它们保存在不同的 df 中。

第三个是字符串连接,我可以自己做。

我真的无法超越df.groupby()

【问题讨论】:

首先进行检查以确保组织。是相同的,将好的过滤到工作的 df 中,将坏的过滤到拒绝的 df 中。其次,将 (1:10:20) 项目的项目连接在一起,并将其存储在新的 car and truck 列中。最后,做一个 pivot_table 以获得所需的输出。 【参考方案1】:

您的原始数据框有一些重复的列,看起来确实是“汽车”数据框和“卡车”数据框。您可以首先拆分原始数据框并分别处理每个数据框,然后在最后合并它们。不用 groupby 也可以。

将原始数据拆分为两个相似的数据帧

import pandas as pd
df = pd.read_csv('rawdata.csv')

car_cols = [
    'gears', 'milesbefore', 'milesafter', 
    'model_car', 'safety_car'
]
df_cars = df[car_cols].copy()


truck_cols = [
    'gears.1', 'milesbefore.1', 'milesafter.1', 
    'model_truck', 'safety_truck'
]
df_trucks = df[truck_cols].copy()

### Rename fields for compatibility
df_cars.rename(
    columns=
        'model_car': 'model',
        'safety_car': 'safety'
    , inplace=True
)

df_trucks.rename(
    columns=
        'model_truck': 'model',
        'safety_truck': 'safety',
        'gears.1': 'gears',
        'milesbefore.1': 'milesbefore',
        'milesafter.1': 'milesafter'
    , inplace=True
)

这里是df_cars,和df_trucks看起来很相似。

   gears  milesbefore  milesafter   model safety
0      1           10          20   honda   NTSB
1      1           10          20   honda   NTFD
2      1           10          20   honda   NRTB
3      1           10          20  toyota   NTFD
4      1           10          20  toyota   NTFD
5      1           10          20  toyota   NRTB
6      1           10          20    jeep   NTSB
7      1           10          20    jeep   NTFD
8      1           10          20    jeep   NRTB
9      1           10          20    jeep   NRTB

然后连接您的列并在每个数据帧上进行旋转

### Do work for cars table
df_cars_final = df_cars.copy().drop_duplicates()
df_cars_final['val'] = df_cars_final['gears'].astype(str)\
                        + ':' + df_cars_final['milesbefore'].astype(str)\
                        + ':' + df_cars_final['milesafter'].astype(str)

df_cars_final = df_cars_final.pivot(
        index='model', columns='safety', values='val'
        ).reset_index().rename_axis(None, axis=1)
        

### Do work for trucks table
df_trucks_final = df_trucks.copy().drop_duplicates()
df_trucks_final['val'] = df_trucks_final['gears'].astype(str)\
                        + ':' + df_trucks_final['milesbefore'].astype(str)\
                        + ':' + df_trucks_final['milesafter'].astype(str)

df_trucks_final = df_trucks_final.pivot(
        index='model', columns='safety', values='val'
        ).reset_index().rename_axis(None, axis=1)

这里是df_cars_final,和df_trucks_final看起来很相似。

    model     NRTB     NTFD     NTSB
0   honda  1:10:20  1:10:20  1:10:20
1    jeep  1:10:20  1:10:20  1:10:20
2  toyota  1:10:20  1:10:20      NaN

然后将两个数据帧合并在一起以获得您想要的输出。

df_final = df_cars_final.merge(
            df_trucks_final, left_index=True, 
            right_index=True,suffixes=('_car', '_truck')
)

print(df_final)
 model_car NRTB_car NTFD_car NTSB_car model_truck NRTB_truck         NTFB NTFD_truck NTSB_truck
0     honda  1:10:20  1:10:20  1:10:20      jaguar  5:100:200  6:1000:2000  5:100:200  5:100:200
1      jeep  1:10:20  1:10:20  1:10:20        merc  5:100:200          NaN  5:100:200        NaN
2    toyota  1:10:20  1:10:20      NaN       volvo  5:100:200          NaN  5:100:200  5:100:200

【讨论】:

我想我想在最后的 df 中使用同一行,意思是 honda and volvo 应该在同一行而不是本田和捷豹,重置索引会改变吗?

以上是关于pandas pivot 或 groupby 多列和控制列的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中使用groupby或pivot在这个pandas数据框中[重复]

Pivot一个多列的pandas数据框架。

Python Pandas groupby 并沿多列排序

Python Pandas DF Pivot 和 Groupby

Pandas Groupby 独特的多列

使用多列的 Pandas groupby 函数