长数据到宽数据转换:`pivot` 与 `pivot_table`

好的,各位观众老爷们,欢迎来到老码农的“数据变形计”专场!今天咱们要聊的,是数据分析界的一项神奇“易容术”——长数据变宽数据!

想象一下,你是一位精明能干的服装店老板,每天都要记录顾客的消费信息。传统的记录方式可能是这样的:

顾客ID 日期 商品 价格
1 2023-10-26 衬衫 100
1 2023-10-26 裤子 200
2 2023-10-26 鞋子 300
2 2023-10-27 帽子 50
1 2023-10-27 外套 400

这种数据结构,我们称之为“长数据”(Long Data)。它就像一条长长的记录,每一行都代表着一个观测值。

但是,如果你想更直观地看到每个顾客都买了什么,或者想按商品来分析销售情况,这种长数据就显得有些力不从心了。这时候,你就需要“易容术”——把长数据变成宽数据!

宽数据(Wide Data)是什么样的呢?它会把一些列的值变成新的列名,让数据更宽广、更扁平。比如,我们可以把上面的数据变成这样:

顾客ID 2023-10-26_衬衫 2023-10-26_裤子 2023-10-26_鞋子 2023-10-27_帽子 2023-10-27_外套
1 100 200 NaN NaN 400
2 NaN NaN 300 50 NaN

你看,是不是一目了然了?每个顾客购买的商品,都直接显示在了对应的列中。

那么,如何才能施展这种神奇的“易容术”呢?在Python的Pandas库中,有两个强大的法宝:pivotpivot_table

接下来,就让老码农来为你详细解读这两个法宝的用法!

法宝一:pivot – 简单粗暴,一锤定音!

pivot 方法就像一位简单粗暴的工匠,它只能处理最简单的情况。如果你的数据满足以下条件,那么 pivot 就是你的最佳选择:

  • 没有重复的索引-列组合: 也就是说,对于相同的索引和列,只能有一个值。
  • 不需要聚合函数: 你只需要把数据从长变宽,不需要进行任何计算。

pivot 方法的基本语法如下:

df.pivot(index='index_col', columns='columns_col', values='values_col')
  • index:指定用作新表格索引的列名。
  • columns:指定用作新表格列名的列名。
  • values:指定填充新表格值的列名。

咱们还是用服装店的数据来举例,首先,我们创建一个DataFrame:

import pandas as pd

data = {'顾客ID': [1, 1, 2, 2, 1],
        '日期': ['2023-10-26', '2023-10-26', '2023-10-26', '2023-10-27', '2023-10-27'],
        '商品': ['衬衫', '裤子', '鞋子', '帽子', '外套'],
        '价格': [100, 200, 300, 50, 400]}
df = pd.DataFrame(data)
print(df)

输出结果:

   顾客ID        日期  商品   价格
0     1  2023-10-26  衬衫  100
1     1  2023-10-26  裤子  200
2     2  2023-10-26  鞋子  300
3     2  2023-10-27  帽子   50
4     1  2023-10-27  外套  400

现在,我们使用 pivot 方法,将“顾客ID”作为索引,“商品”作为列,“价格”作为值:

pivot_df = df.pivot(index='顾客ID', columns='商品', values='价格')
print(pivot_df)

输出结果:

商品   外套    帽子    衬衫    裤子    鞋子
顾客ID                        
1   400.0   NaN  100.0  200.0   NaN
2     NaN  50.0   NaN   NaN  300.0

怎么样,是不是很简单? pivot 方法就像一把锋利的刻刀,直接把数据按照你的意愿雕刻成了想要的形状。

但是! pivot 方法有一个致命的缺点:它不能处理重复的索引-列组合。如果你的数据中存在这种情况,pivot 方法就会毫不留情地抛出一个错误,让你措手不及。 😱

举个例子,如果我们的数据中,顾客1在2023-10-26这一天买了两次衬衫,那么 pivot 方法就会报错:

data = {'顾客ID': [1, 1, 2, 2, 1, 1],
        '日期': ['2023-10-26', '2023-10-26', '2023-10-26', '2023-10-27', '2023-10-27', '2023-10-26'],
        '商品': ['衬衫', '裤子', '鞋子', '帽子', '外套', '衬衫'],
        '价格': [100, 200, 300, 50, 400, 120]}
df = pd.DataFrame(data)

try:
  pivot_df = df.pivot(index='顾客ID', columns='商品', values='价格')
  print(pivot_df)
except ValueError as e:
  print(f"Error: {e}")

输出结果:

Error: Index contains duplicate entries, cannot reshape

看到没? pivot 方法直接罢工了!

这时候,我们就需要请出我们的第二个法宝:pivot_table

法宝二:pivot_table – 包容万象,化腐朽为神奇!

pivot_table 方法就像一位经验丰富的炼金术士,它不仅可以处理重复的索引-列组合,还可以进行各种聚合计算,把复杂的数据变成你想要的模样。

pivot_table 方法的基本语法如下:

pd.pivot_table(data, values='values_col', index='index_col', columns='columns_col', aggfunc='aggregate_function')
  • data:指定要进行透视的数据。
  • values:指定填充新表格值的列名。
  • index:指定用作新表格索引的列名。
  • columns:指定用作新表格列名的列名。
  • aggfunc:指定聚合函数。常用的聚合函数包括:'mean'(平均值)、'sum'(求和)、'count'(计数)、'min'(最小值)、'max'(最大值)等等。

咱们还是用刚才报错的数据来举例,这次我们使用 pivot_table 方法,并指定聚合函数为 'sum',表示对重复的索引-列组合的值进行求和:

pivot_table_df = pd.pivot_table(df, values='价格', index='顾客ID', columns='商品', aggfunc='sum')
print(pivot_table_df)

输出结果:

商品   外套    帽子    衬衫    裤子    鞋子
顾客ID                        
1   400.0   NaN  220.0  200.0   NaN
2     NaN  50.0   NaN   NaN  300.0

你看,即使有重复的索引-列组合,pivot_table 方法也能轻松应对,并按照我们指定的聚合函数进行计算。

pivot_table 方法的强大之处还在于,它可以进行各种复杂的聚合计算。比如,我们可以计算每个顾客购买的商品数量:

pivot_table_df = pd.pivot_table(df, values='价格', index='顾客ID', columns='商品', aggfunc='count')
print(pivot_table_df)

输出结果:

商品   外套    帽子    衬衫    裤子    鞋子
顾客ID                        
1   1.0   NaN  2.0  1.0   NaN
2     NaN  1.0   NaN   NaN  1.0

或者,我们可以计算每个顾客购买的商品价格的平均值:

pivot_table_df = pd.pivot_table(df, values='价格', index='顾客ID', columns='商品', aggfunc='mean')
print(pivot_table_df)

输出结果:

商品   外套    帽子    衬衫    裤子    鞋子
顾客ID                        
1   400.0   NaN  110.0  200.0   NaN
2     NaN  50.0   NaN   NaN  300.0

总而言之,pivot_table 方法就像一位百变星君,可以根据你的需求,进行各种灵活的变形和计算。

pivot vs. pivot_table:一场巅峰对决!

说了这么多,相信大家对 pivotpivot_table 都有了一定的了解。那么,它们之间到底有什么区别呢?我们来总结一下:

特性 pivot pivot_table
处理重复值 无法处理,会报错 ❌ 可以处理,需要指定聚合函数 ✅
聚合计算 不支持 ❌ 支持,可以进行各种聚合计算 ✅
灵活性 较低 😔 较高 😊
使用场景 数据干净,没有重复值,不需要聚合计算时 🤓 数据复杂,可能存在重复值,需要进行聚合计算时 😎

简单来说,pivot 适合处理简单的数据变形,而 pivot_table 适合处理复杂的数据分析。就像一把瑞士军刀,pivot_table 功能更多,更实用。

实战演练:用 pivot_table 玩转电影评分数据!

光说不练假把式!为了让大家更好地掌握 pivot_table 的用法,我们来做一个实战演练。

假设我们有一份电影评分数据,包含了用户ID、电影ID和评分:

用户ID 电影ID 评分
1 101 4
1 102 5
2 101 3
2 103 2
3 102 4
3 103 5

我们想要把这份数据变成宽数据,让每一行代表一个用户,每一列代表一部电影,单元格中的值代表用户对该电影的评分。

首先,我们创建一个DataFrame:

import pandas as pd

data = {'用户ID': [1, 1, 2, 2, 3, 3],
        '电影ID': [101, 102, 101, 103, 102, 103],
        '评分': [4, 5, 3, 2, 4, 5]}
df = pd.DataFrame(data)
print(df)

输出结果:

   用户ID  电影ID  评分
0     1   101   4
1     1   102   5
2     2   101   3
3     2   103   2
4     3   102   4
5     3   103   5

现在,我们使用 pivot_table 方法,将“用户ID”作为索引,“电影ID”作为列,“评分”作为值:

pivot_table_df = pd.pivot_table(df, values='评分', index='用户ID', columns='电影ID')
print(pivot_table_df)

输出结果:

电影ID  101  102  103
用户ID             
1     4.0  5.0  NaN
2     3.0  NaN  2.0
3     NaN  4.0  5.0

搞定!我们成功地把电影评分数据变成了宽数据,可以更方便地进行用户画像和电影推荐等分析。

高级技巧:玩转 pivot_table 的更多姿势!

除了基本的用法之外,pivot_table 还有很多高级技巧,可以让你玩转各种复杂的数据分析场景。

  • 多层索引和列: pivot_table 支持多层索引和列,可以让你更细粒度地分析数据。
  • 自定义聚合函数: 除了内置的聚合函数之外,你还可以自定义聚合函数,满足更个性化的需求。
  • 处理缺失值: pivot_table 提供了 fill_value 参数,可以让你自定义缺失值的填充方式。
  • 添加总计: pivot_table 提供了 margins 参数,可以让你添加行和列的总计。

这些高级技巧,就留给大家自己去探索和学习啦!相信只要你多多实践,一定能成为 pivot_table 的高手!

总结:数据变形,其乐无穷!

今天,我们一起学习了如何使用 pivotpivot_table 这两个法宝,将长数据变成宽数据。数据变形是数据分析中非常重要的一环,它可以帮助我们更好地理解数据、发现规律、做出决策。

希望通过今天的学习,大家能够掌握数据变形的技巧,在数据分析的道路上越走越远!

最后,老码农祝大家编码愉快,bug退散!咱们下期再见! 👋

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注