Pandas学习笔记(七)

数据集的重塑和透视

该文章内容为《Pandas数据分析实战》的学习笔记

导入需要的包

import pandas as pd

宽数据和窄数据

宽数据集和窄数据集的名称反应了数据集的扩展方向

  • 宽数据集:数据越多,数据集越宽

  • 窄数据集:数据越多,数据越长

由DataFrame创建数据透视表

pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/sales_by_employee.csv").head()
# 将Date列中的字符串转换为datetime导入
sales = pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/sales_by_employee.csv"
                    , parse_dates = ["Date"])
sales

导入数据之后,将介绍一下如何使用数据透视表来聚合数据集内的数据

pivot_table方法

创建数据透视表:

  • 选择要做聚合操作的列

  • 选择要应用于该列的聚合操作

  • 选择用于数据集分组的列

  • 确定是否将"分组"放置在行轴、列轴或两个轴上

使用pivot_table方法。该方法的index参数用于设定数据透视表的索引标签。Pandas将使用该列中的唯一真值对结果进行分组

sales.pivot_table(index = "Date", values=["Revenue", "Expenses"], aggfunc="mean")

其中values参数为选择需要操作的列,必须是数字列;aggfunc参数为需要执行的操作。比如说还可以:

sales.pivot_table(index = "Date", values="Revenue", aggfunc="sum")

对索引级别进行堆叠和取消堆叠

根据员工姓名和日期来调整sales数据集,并显示收入值

by_name_and_date = sales.pivot_table(
    index = "Name",
    columns = "Date",
    values = "Revenue",
    aggfunc = "sum"
)
by_name_and_date

通过stack方法,可以将索引级别从列轴移到行轴。由于转换之后只有一列数据,此时数据将会被转换为Series

by_name_and_date.stack()

注意在DataFrame中为了结构完整使用NaN来保留单元格,这里转换为Series了就不需要了,所有就没有NaN了

unstack可以将索引从行轴移动到列轴

融合数据集
video_game_sales = pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/video_game_sales.csv")
video_game_sales.head()

我们可以观察到,表中存储的数据是销售额,而列名确实地区,所以如果我们想要增加销售额的数据,我们需要横向扩展,所以这是一个宽数据集。也就是说如果列名为Sale则这是一个窄数据集

Pandas使用melt方法来分解一个DataFrame(数据分解是将一个宽数据集转换为一个窄数据集的过程)。该方法接受两个主要参数:

  • id_vars参数识别标识符,宽数据集在该列聚合

  • value_vars参数接受一(多)列,它的值将分解并存储在一个新列中

video_game_sales.melt(
    id_vars = "Name",
    value_vars = ["NA", "EU", "JP", "Other"]
)

将var_name和value_name来自定义分解DataFrame的列名

video_game_sales.melt(
    id_vars = "Name",
    value_vars = ["NA", "EU", "JP", "Other"],
    var_name = "Region",
    value_name = "Sales"
)

窄数据比宽数据更容易聚合,我们可以使用pivot_table方法用几行代码完成这个任务

展开值列表

recipes = pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/recipes.csv")
recipes.head()

我们可以看到Ingredients列中的元素由多个元素组成,如果我们像下面这样做,会得到一个我们不希望看到的结果

recipes["Ingredients"] = recipes["Ingredients"].str.split(",")
recipes

如果我们想要将每个列表的值分布在多行,我们可以使用explode方法为Series中的每个列元素创建一个单独的行

recipes.explode("Ingredients")

代码挑战

本节中要用到两个数据集,其中 used_cars.csv 数据集是分类网站 Craigslist 上待售二手车的列表,每行包括汽车的制造商、生产年份、燃料类型、变速器类型和价格的相关信息

minimum_wage.csv 数据集是美国最低工资的集合。该数据集有一个州列和多个代表具体年份的列

本节需要解决的问题如下:

  1. 对汽车的价格进行汇总,在行轴上按燃料类型对结果进行分组。
  2. 汇总汽车的数量。在索引轴上按制造商对结果进行分组,在列轴上按变速器类型对结果进行分组,显示行和列的小计。
  3. 计算汽车价格的平均值。在索引轴上按年份和燃料类型对结果进行分组,在列轴上按变速器类型对结果进行分组。
  4. 对于问题(3)得到的 DataFrame,将变速器类型从列轴移到行轴。
  5. min_wage 从宽格式转换为窄格式。换句话说,将原来 2010 年到 2017 年的 8 列转换成一列。
解决方案
cars = pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/used_cars.csv")
min_wage = pd.read_csv("pandas-in-action-master/chapter_08_reshaping_and_pivoting/minimum_wage.csv")
cars
# 1
cars.pivot_table(values = "Price", index = "Fuel", aggfunc = "sum")

# 2
cars.pivot_table(values = "Price", index = "Manufacturer", columns = "Transmission", aggfunc = "count", margins = True)

# 3
cars.pivot_table(
    values = "Price",
    index = ["Year", "Fuel"],
    columns = "Transmission",
    aggfunc = "mean"
)

# 4
report = cars.pivot_table(
    values = "Price",
    index = ["Year", "Fuel"],
    columns = "Transmission",
    aggfunc = "mean"
)
report.stack()

# 5
min_wage.melt(id_vars = "State", value_vars = ["2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017"])

关注公众号小辛到处学,发送1,获取文中的数据资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值