Task 4 变形 学习笔记

一、透视表

pivot函数、pivot_table函数

一般状态下,数据在DataFrame会以压缩(stacked)状态存放,例如上面的Gender,两个类别被叠在一列中。pivot_table函数可将某一原列转为新列,新列中的值由其他列确定。请体会pivot_table函数中参数的作用:

df.pivot(index='ID',columns='Gender',values='Height').head()
# 将columns的值展开,填入指定的values
pd.pivot_table(df, index='ID',columns='Gender',values='Height').head()

image-20200428210706298

其他一些常用的参数:

  • aggfunc:对组内进行聚合统计,默认统计函数为mean
  • margins = True:汇总边际状态
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum'], margins=True).head()
# 默认 margins_name='All'

image-20200428211037540

  • 设置行、列、值为多级
pd.pivot_table(df,index=['School','Class'],
              columns=['Gender','Address'],
              values=['Height','Weight'])

image-20200428211145875

crosstab函数(交叉表)

交叉表是一种特殊的透视表,典型的用途如分组统计。下面统计街道和性别分组的频数:

pd.crosstab(index=df['Address'], columns=df['Gender'])

在这里插入图片描述

crosstab函数的一些重要参数:

  • values和aggfunc:分组对某些数据进行聚合操作,这两个参数必须成对出现
pd.crosstab(index=df['Address'],columns=df['Gender'],
            values=np.random.randint(1,20,df.shape[0]),aggfunc='min')
#默认参数等于如下方法:
#pd.crosstab(index=df['Address'],columns=df['Gender'],values=1,aggfunc='count')

交叉表的默认函数中,默认为计数方法,此处实验采用的min方法,相信你可以比较出他们的不同,以及理解values和aggfunc成对出现的原因:

image-20200428213115852

  • normalize参数,可选’all’,‘index’,'columns’参数值。

normalize与margins也是成对出现的,归一化的值需要在边际上呈现。

pd.crosstab(index=df['Address'], columns=df['Gender'],normalize='all',margins=True,margins_name='归一化')

image-20200428213450957

二、其他变形方法

melt函数

melt函数可以认为是pivot函数的逆操作,将unstacked状态的数据,压缩成stacked,使“宽”的DataFrame变“窄”。melt中的参数变量id_vars表示需要保留的列,value_vars表示需要stack的一组列。

# 展开Gender这一列,并将Math列中的值赋给新列
pivoted = df.pivot(index='ID',columns='Gender',values='Math')

# 保留ID列,合并F、M列为一列,value_vars设置,然后去除空值列...
result = pivoted.reset_index().melt(id_vars=['ID'],value_vars=['F','M'],value_name='新Math').dropna().set_index('ID').sort_index()

display(result.head())#检验是否与展开前的df相同,可以分别将这些链式方法的中间步骤展开,看看是什么结果
# result.equals(df_m.set_index('ID'))

压缩与展开

(1)stack:这是最基础的变形函数,总共只有两个参数:level和dropna

stack函数可以看做将横向的索引放到纵向,因此功能类似与melt,参数level可指定变化的列索引是哪一层(或哪几层,需要列表)

(2) unstack:stack的逆函数,功能上类似于pivot_table

三、哑变量与因子化

Dummy Variable(哑变量)

get_dummies函数的功能主要是进行one-hot编码。接下来,将Class、Gender变量转化为哑变量,并加入第三列Weight的数值:

df_d = df[['Class','Gender','Weight']]
pd.get_dummies(df_d[['Class','Gender']]).join(df_d['Weight']).head()
# 可选prefix参数添加前缀,prefix_sep添加分隔符

image-20200428220246517

factorize方法

factorize方法主要用于自然数编码,缺失值被记为-1,sort参数表示是否排序后赋值:

codes, uniques = pd.factorize(['b', None, 'a', 'c', 'b'], sort=True)
display(codes)
display(uniques)
array([ 1, -1,  0,  2,  1])
array(['a', 'b', 'c'], dtype=object)

四、问题与练习

【问题一】 上面提到了许多变形函数,如melt/crosstab/pivot/pivot_table/stack/unstack函数,请总结它们各自的使用特点。
【问题二】 变形函数和多级索引是什么关系?哪些变形函数会使得索引维数变化?具体如何变化?
【问题三】 请举出一个除了上文提过的关于哑变量方法的例子。
【问题四】 使用完stack后立即使用unstack一定能保证变化结果与原始表完全一致吗?
【问题五】 透视表中涉及了三个函数,请分别使用它们完成相同的目标(任务自定)并比较哪个速度最快。
【问题六】 既然melt起到了stack的功能,为什么再设计stack函数?

【练习一】 继续使用上一章的药物数据集:

# (a) 现在请你将数据表转化成如下形态,每行需要显示每种药物在每个地区的10年至17年的变化情况,且前三列需要排序

result = pd.pivot_table(data, index=['State','COUNTY','SubstanceName'], columns='YYYY',values='DrugReports',
              fill_value='-').reset_index().rename_axis(columns={'YYYY':''})
result.head()

在这里插入图片描述

(b)恢复

result2 = result.melt(id_vars=result.columns[:3], 
                     value_vars=result.columns[4:],
                     var_name='YYYY',value_name='DrugReports')
result2.head()

在这里插入图片描述

【练习二】 现有一份关于某地区地震情况的数据集,请解决如下问题:

(a) 现在请你将数据表转化成如下形态,将方向列展开,并将距离、深度和烈度三个属性压缩:

import pandas as pd
import numpy as np
data2 = pd.read_csv('data/Earthquake.csv')
data2.head()

temp = pd.pivot_table(data2, index=['日期','时间','维度','经度'], columns=['方向'], values=['距离','深度','烈度'],fill_value='-')

temp = temp.stack(0).rename_axis(index={None:'地震参数'}) ##
temp.head()

在这里插入图片描述
b) 现在请将(a)中的结果恢复到原数据表,并通过equal函数检验初始表与新的结果是否一致(返回True)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值