宽数据到长数据转换:`melt` 函数的应用

宽数据变身记:melt 函数,数据界的变形金刚!

各位数据英雄们,晚上好!我是你们的老朋友,数据界的段子手,今天要跟大家聊聊数据变形的魔法——宽数据到长数据的转换。啥?你问我什么是宽数据,什么是长数据?别急,搬好小板凳,听我慢慢道来,保证你听完之后,也能像孙悟空一样,挥舞着金箍棒(melt 函数),把你的数据玩转于股掌之间!

第一幕:数据世界的两极分化——宽与长的爱恨情仇

咱们先来认识一下数据界的两大门派:宽数据和长数据。

  • 宽数据: 想象一下,你手里拿着一张Excel表格,每一列都代表一个不同的变量,每一行代表一个独立的个体。就好比一个班级里,每一列是学生的姓名、年龄、性别、考试成绩、爱好等等,而每一行就是一个学生。这种数据格式,信息量大,一目了然,就像一位身材丰腴的美人,曲线毕露,尽收眼底。

    | 学生姓名 | 年龄 | 性别 | 语文成绩 | 数学成绩 | 英语成绩 |
    | -------- | ---- | ---- | -------- | -------- | -------- |
    | 张三     | 10   | 男   | 90       | 85       | 92       |
    | 李四     | 11   | 女   | 88       | 95       | 80       |
    | 王五     | 10   | 男   | 75       | 82       | 88       |

    优点: 直观易懂,方便人类阅读。
    缺点: 浪费存储空间,不利于某些统计分析,比如你想统计所有科目的平均成绩,就得手动操作,效率低下。

  • 长数据: 再想象一下,你把这张Excel表格竖起来,让变量名变成一列,对应的值变成另一列。还是刚才的班级例子,现在变成每一行代表一个学生在某个科目上的成绩。就像一位苗条的舞者,身姿婀娜,更有韵味。

    | 学生姓名 | 科目   | 成绩 |
    | -------- | ------ | ---- |
    | 张三     | 语文   | 90   |
    | 张三     | 数学   | 85   |
    | 张三     | 英语   | 92   |
    | 李四     | 语文   | 88   |
    | 李四     | 数学   | 95   |
    | 李四     | 英语   | 80   |
    | 王五     | 语文   | 75   |
    | 王五     | 数学   | 82   |
    | 王五     | 英语   | 88   |

    优点: 节省存储空间,方便进行统计分析,比如计算平均成绩、绘制各种图表。
    缺点: 不够直观,不如宽数据容易理解。

宽数据和长数据就像一对欢喜冤家,各有千秋,各有优劣。在不同的场景下,我们需要选择不同的数据格式。但是,有时候我们拿到的数据是宽格式的,而我们需要的是长格式的,怎么办呢?别慌!我们的主角——melt 函数,闪亮登场!✨

第二幕:melt 函数的华丽变身——数据变形金刚

melt 函数,顾名思义,就是“融化”的意思。它可以将宽数据“融化”成长数据,就像冰雪融化成水一样,改变数据的形态。

melt 函数是 Pandas 库中的一个函数,所以在使用之前,我们需要先导入 Pandas 库。

import pandas as pd

melt 函数的基本语法如下:

pd.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)

参数解释:

  • frame:需要进行转换的 DataFrame 对象。
  • id_vars:不需要进行转换的列,也就是保持不变的列。相当于身份证,用来识别每个个体。
  • value_vars:需要进行转换的列,也就是要“融化”的列。如果没有指定,默认转换所有非 id_vars 的列。
  • var_name:转换后的变量名,也就是原来列名的名称。默认是 'variable'
  • value_name:转换后的值名,也就是原来列对应的值的名称。默认是 'value'
  • col_level:如果列名是多层索引,指定要使用的层级。
  • ignore_index:是否忽略原来的索引,重新生成新的索引。默认是 True

是不是感觉有点晕?没关系,咱们用几个例子来加深理解。

例子1:最简单的变形

假设我们有以下宽数据:

data = {'学生姓名': ['张三', '李四', '王五'],
        '语文成绩': [90, 88, 75],
        '数学成绩': [85, 95, 82],
        '英语成绩': [92, 80, 88]}
df = pd.DataFrame(data)
print(df)

输出:

  学生姓名  语文成绩  数学成绩  英语成绩
0   张三    90    85    92
1   李四    88    95    80
2   王五    75    82    88

现在,我们想把它转换成长数据,将语文成绩、数学成绩、英语成绩这三列“融化”成两列:科目和成绩。

df_melted = pd.melt(df, id_vars=['学生姓名'], value_vars=['语文成绩', '数学成绩', '英语成绩'], var_name='科目', value_name='成绩')
print(df_melted)

输出:

  学生姓名    科目  成绩
0   张三  语文成绩  90
1   李四  语文成绩  88
2   王五  语文成绩  75
3   张三  数学成绩  85
4   李四  数学成绩  95
5   王五  数学成绩  82
6   张三  英语成绩  92
7   李四  英语成绩  80
8   王五  英语成绩  88

看,是不是很简单?我们指定了 id_vars['学生姓名'],表示学生姓名这一列保持不变;指定了 value_vars['语文成绩', '数学成绩', '英语成绩'],表示这三列要进行转换;指定了 var_name'科目',表示转换后的变量名是“科目”;指定了 value_name'成绩',表示转换后的值名是“成绩”。

例子2:省略 value_vars

如果我们想转换所有非 id_vars 的列,可以省略 value_vars 参数。

df_melted = pd.melt(df, id_vars=['学生姓名'], var_name='科目', value_name='成绩')
print(df_melted)

输出结果和上面一样。

例子3:自定义列名

我们可以根据自己的需求,自定义转换后的列名。

df_melted = pd.melt(df, id_vars=['学生姓名'], var_name='examination', value_name='score')
print(df_melted)

输出:

  学生姓名 examination  score
0   张三        语文成绩     90
1   李四        语文成绩     88
2   王五        语文成绩     75
3   张三        数学成绩     85
4   李四        数学成绩     95
5   王五        数学成绩     82
6   张三        英语成绩     92
7   李四        英语成绩     80
8   王五        英语成绩     88

例子4:多层索引列名

如果 DataFrame 的列名是多层索引,我们可以使用 col_level 参数指定要使用的层级。

假设我们有以下 DataFrame:

data = {'学生姓名': ['张三', '李四', '王五'],
        ('成绩', '语文'): [90, 88, 75],
        ('成绩', '数学'): [85, 95, 82],
        ('成绩', '英语'): [92, 80, 88]}
df = pd.DataFrame(data)
print(df)

输出:

  学生姓名  (成绩, 语文)  (成绩, 数学)  (成绩, 英语)
0   张三       90       85       92
1   李四       88       95       80
2   王五       75       82       88
df_melted = pd.melt(df, id_vars=['学生姓名'], var_name='科目', value_name='成绩', col_level=1)
print(df_melted)

输出:

  学生姓名    科目  成绩
0   张三    语文  90
1   李四    语文  88
2   王五    语文  75
3   张三    数学  85
4   李四    数学  95
5   王五    数学  82
6   张三    英语  92
7   李四    英语  80
8   王五    英语  88

我们指定了 col_level=1,表示使用第二层索引作为变量名。

总结:

melt 函数就像一个魔法棒,可以轻松地将宽数据转换成长数据。掌握了 melt 函数,你就可以根据自己的需求,灵活地处理各种数据格式,让数据分析更加得心应手。

第三幕:melt 函数的应用场景——数据变形的舞台

melt 函数的应用场景非常广泛,只要涉及到数据格式转换,都可以派上用场。下面列举一些常见的应用场景:

  • 时间序列数据: 比如股票价格、气温变化等,通常以宽格式存储,每一列代表一个时间点。我们可以使用 melt 函数将它转换成长格式,方便进行时间序列分析。

  • 调查问卷数据: 问卷调查的结果通常以宽格式存储,每一列代表一个问题。我们可以使用 melt 函数将它转换成长格式,方便进行统计分析。

  • 实验数据: 实验数据通常以宽格式存储,每一列代表一个实验条件。我们可以使用 melt 函数将它转换成长格式,方便进行统计分析。

  • 数据库数据: 从数据库中导出的数据,有时是宽格式的,我们需要使用 melt 函数将它转换成长格式,才能进行后续的处理。

总之,只要你需要将宽数据转换成长数据,melt 函数就是你的最佳选择。

第四幕:melt 函数的进阶技巧——数据变形的高阶玩法

除了基本用法之外,melt 函数还有一些进阶技巧,可以让你更加灵活地处理数据。

  • 结合其他函数使用: melt 函数可以和其他 Pandas 函数结合使用,比如 groupby()pivot_table() 等,实现更加复杂的数据分析。

  • 处理缺失值: 在进行数据转换之前,可以先处理缺失值,避免影响转换结果。

  • 数据类型转换: 在进行数据转换之后,可以根据需要,将数据类型转换为合适的类型。

  • 自定义排序: 可以自定义转换后的数据的排序方式,让数据更加整洁。

掌握了这些进阶技巧,你就可以像一位经验丰富的魔术师,随心所欲地玩转数据,让数据焕发出新的光彩。

结尾:数据变形,永无止境!

数据世界千变万化,数据格式也层出不穷。掌握了 melt 函数,只是我们数据探索之旅的第一步。在未来的日子里,我们还需要不断学习新的数据处理技巧,才能在数据海洋中自由遨游,发现更多的宝藏。

希望今天的分享对大家有所帮助。记住,数据分析不仅仅是一门技术,更是一门艺术。让我们一起努力,用数据创造价值,用代码改变世界!💪

最后,送给大家一句名言:

数据在手,天下我有! 🚀

发表回复

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