重塑 Pandas DataFrame 中的数据
在本 Python 和 Pandas 数据清洗系列的第六部分中,我们将介绍一些用于合并数据的更简单的方法。
引言
本文是《使用 Python 和 Pandas 进行数据清洗》系列的一部分。其目标是帮助开发人员快速上手数据科学工具和技术。
如果您想查看该系列中的其他文章,可以在此处找到它们。
- 第一部分 - Jupyter 和 Pandas 入门
- 第二部分 - 将 CSV 和 SQL 数据加载到 Pandas 中
- 第三部分 - 在 Pandas 中更正缺失数据
- 第四部分 - 在 Pandas 中合并多个数据集
- 第五部分 - 在 Pandas DataFrame 中清理数据
- 第六部分 - 在 Pandas DataFrame 中重塑数据
- 第七部分 - 使用 Seaborn 和 Pandas 进行数据可视化
有时,即使您清理了数据集,您仍然需要重塑 Pandas DataFrame,才能充分利用数据。重塑是指操纵表格结构以形成不同的数据集,例如将“宽”数据表变为“长”。
如果您使用过 Excel 中的数据透视表或内置的 pivot 和 crosstab 功能(许多关系数据库中包含),您将会对此感到熟悉。
例如,上面的表格(来自 Pandas 文档)已通过透视、堆叠或取消堆叠进行了重塑。
pivot
方法接受具有多个索引的大型数据集并对其进行汇总stack
方法接受具有多个索引的表格并将它们分组unstack
方法接受具有多个唯一列的表格并将它们取消分组
在此阶段,我们将研究一些使用 Pandas 重塑数据的方法。我们将看到如何使用 DataFrame 的透视和堆叠来获得数据的不同视图。
请注意,我们已经为本系列模块创建了一个完整的 Jupyter Notebook,其中包含源数据文件,您可以下载并在本地安装。
透视 Pandas DataFrame
使用 Pandas,我们可以使用 pivot
函数从现有 DataFrame 创建新的 DataFrame。目前,我们的表格按购买 ID 索引,但让我们将之前创建的 combinedData
表透视为更有趣的内容。
首先,让我们通过启动一个新的代码块并添加以下内容来尝试以下 pivot
方法
productsByState = combinedData.pivot(index='product_id', columns='company', values='paid')
结果如下:
运行此命令会生成重复索引错误,因为 pivot
仅适用于具有唯一键的 DataFrame。
但是还有另一种方法可以给我们提供避免这种情况的结果。pivot_table
的工作方式很像 pivot,除了它聚合重复值而不是生成错误。
pivot_table
方法接受大型数据集,并通过聚合重复项来对其进行汇总
让我们使用默认值来使用此方法
productsByState = combinedData.pivot_table(index=['product_id', 'product'], columns='state', values='paid')
您可以在此处看到结果
这将生成一个 DataFrame,其中包含产品列表以及每个州/省的平均值。这并不是很有用,所以让我们更改聚合方法
reshapedData = combinedData.pivot_table(index=['product_id', 'product'], columns='state', values='paid', aggfunc=np.sum)
reshapedData = reshapedData.fillna(0)
print(reshapedData.head(10))
现在生成一个产品表,其中包含这些产品按州/省的所有销售额的总和。此方法中的第二行还删除了 NaN 值并将其替换为 0,因为假设这些产品在该州/省没有销售额。
在 Pandas DataFrame 中对数据进行分组
我们将看到的另一个重塑活动是将数据元素分组在一起。让我们回到原来的大型 DataFrame,并创建一个新的 DataFrame,将单个客户的交易分组在一起。
groupby
方法接受大型数据集并按列值进行分组
启动一个新的代码块并添加
volumesData = combinedData.groupby(by='customer_id') print(volumesData.head(10))
结果如下:
它看起来并没有真正做任何事情,因为我们的 DataFrame 是在 purchase_id
上索引的。
让我们添加一个聚合函数来汇总数据,以便我们的分组按预期工作
volumesData = combinedData.groupby(by='customer_id').sum()
print(volumesData.head(10))
同样,这是结果
这以我们期望的方式对我们的数据集进行分组,但我们似乎缺少一些列,并且 purchase_id
实际上没有任何意义,所以让我们扩展我们的 groupby
方法并删除 purchase_id
列
volumesData = combinedData.groupby(by=['customer_id','first_name','last_name','product_id','product']).sum()
volumesData.drop(columns='purchase_id', inplace=True)
print(volumesData.head(10))
这是我们的新结果
最终结果看起来非常好,并且让我们很好地了解客户正在购买什么、数量以及他们支付的价格。
最后,我们将对我们的数据集进行另一次 groupby
更改。添加以下内容以创建按州/省划分的总计 DataFrame
totalsData = combinedData.groupby(by='state').sum().reset_index()
totalsData.drop(columns=['purchase_id','customer_id','product_id'], inplace=True)
这里的关键变化是我们在 sum
方法之后添加了 reset_index
方法。这是为了确保生成的 DataFrame 具有可用于我们的可视化工作的索引。
摘要
我们采用了完整的、干净的数据集,并以几种不同的方式对其进行了重塑,从而使我们对数据有了更深入的了解。
接下来,我们将研究可视化,并了解它们是如何成为呈现数据和确保结果清晰的重要工具。
标题图片来源:http://ohi-science.org/data-science-training/tidyr