从行到列重塑pandas数据帧

Chr*_*her 8 python reshape dataframe pandas pandas-groupby

我正在尝试重塑我的数据.乍一看,它听起来像一个转置,但事实并非如此.我尝试过融化,堆叠/取消堆叠,连接等.

用例

我希望每个唯一个体只有一行,并将所有作业历史记录放在列上.对于客户端,可以更容易地跨行读取信息而不是读取列.

这是数据:

import pandas as pd
import numpy as np

data1 = {'Name': ["Joe", "Joe", "Joe","Jane","Jane"],
        'Job': ["Analyst","Manager","Director","Analyst","Manager"],
        'Job Eff Date': ["1/1/2015","1/1/2016","7/1/2016","1/1/2015","1/1/2016"]}
df2 = pd.DataFrame(data1, columns=['Name', 'Job', 'Job Eff Date'])

df2
Run Code Online (Sandbox Code Playgroud)

这就是我想要它的样子: 所需的输出表

在此输入图像描述

piR*_*red 7

.Tgroupby

def tgrp(df):
    df = df.drop('Name', axis=1)
    return df.reset_index(drop=True).T

df2.groupby('Name').apply(tgrp).unstack()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


说明

groupby返回一个对象,其中包含有关如何对原始系列或数据帧进行分组的信息.groupby我们可以先将df2.groupby('Name')一个变量分配给一个变量(我经常这样做),而不是使用某种类型的后续动作执行gb.

gb = df2.groupby('Name')
Run Code Online (Sandbox Code Playgroud)

在这个对象上,gb我们可以调用.mean()以获得每个组的平均值.或者.last()获取每个组的最后一个元素(行).或者.transform(lambda x: (x - x.mean()) / x.std())在每个组中进行zscore转换.如果您想要在没有预定义功能的组中执行某些操作,则仍然存在.apply().

.apply()一个groupby对象与一个对象不同dataframe.对于数据框,.apply()将可调用对象作为其参数,并将该可调用对象应用于对象中的每个列(或行).传递给该callable的对象是a pd.Series.当您.applydataframe上下文中使用时,记住这一事实是有帮助的.在groupby对象的上下文中,传递给callable参数的对象是数据帧.实际上,该数据帧是由指定的组之一groupby.

当我编写要传递给的函数时groupby.apply,我通常会定义参数df以反映它是一个数据帧.

好的,我们有:

df2.groupby('Name').apply(tgrp)
Run Code Online (Sandbox Code Playgroud)

这会为每个子帧生成一个子数据帧'Name',并将该子数据帧传递给该函数tgrp.然后,该groupby对象将已经通过该tgrp功能的所有这些组重新组合在一起.

它看起来像这样.

在此输入图像描述

我把OP最初的尝试简单地转移到了心上.但我必须先做一些事情.我完成了:

df2[df2.Name == 'Jane'].T
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

df2[df2.Name == 'Joe'].T
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

手动组合这些(不groupby):

pd.concat([df2[df2.Name == 'Jane'].T, df2[df2.Name == 'Joe'].T])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

哇!现在那很难看.显然索引值[0, 1, 2]不与网格相匹配[3, 4].所以让我们重置一下.

pd.concat([df2[df2.Name == 'Jane'].reset_index(drop=True).T,
           df2[df2.Name == 'Joe'].reset_index(drop=True).T])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

那好多了.但现在我们正准备进入该领土groupby.所以让它来处理它.

回到

df2.groupby('Name').apply(tgrp)
Run Code Online (Sandbox Code Playgroud)

这里唯一缺少的是我们想要取消堆叠结果以获得所需的输出.

在此输入图像描述