我们相信:世界是美好的,你是我也是。 来玩一下解压小游戏吧!

pandas里面有一个melt()方法,操作对象是dataframe。可以把一部分列数据变成横向的行数据。这个列变成行的效果,转换的也并不完全。这个函数的主要功能是把部分列数据变成行数据,也有部分列数据保持不变。同时也会有数据增生的现象发生,原列标签会变成主体内容,同时生成新的列标签。总之,就是和行列互换的需求是完全不同的结果。

苏南大叔:如何利用pandas的melt()方法,实现宽表转长表的操作? - pandas-melt
如何利用pandas的melt()方法,实现宽表转长表的操作?(图3-1)

大家好,这里是苏南大叔的"程序如此灵动"博客,本文记录pandasmelt()方法。测试环境:win10python@3.11.0numpy@1.24.2pandas@1.5.3。而且这个melt()函数还有个副作用,就是会增大数据量,作为主键的列数据量会明显成倍增加。

melt,融化。

melt()函数原型

Pandas.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)
Python
  • frame:要处理的dataframe数据。
  • id_varstuple/list/ndarray,用作标识变量的列,即不需要被转换的列名。
  • value_varstuple/list/ndarray,即将被转换的列。 如果未指定,则使未被设置为id_vars的所有列。
  • var_name:标量,用于“变量”列的名称。 如果未指定,则使用variable
  • value_name:标量,默认为value,用于value列的名称。
  • col_levelintstr,如果列是多重索引的,则使用此级别来融化。这个一般情况下用不到。
  • ignore_index:默认为True,也就是忽略原有的行名,从头开始计数行名。

原始数据

import pandas as pd
df = pd.DataFrame({
    'name': ['虎子', '老许', '小黑'],
    'foot': [10, 20, 30],
    'height': [80, 30, 50]
},index=["a1","a2","a3"])
print(df)
Python

输出:

     name  foot  height
a1   虎子    10      80
a2   老许    20      30
a3   小黑    30      50
Plain text

默认melt()效果

默认的转换效果,全部的列都被横过来了。新生成

df_melt = pd.melt(df)
print(df_melt)
Python

输出:

  variable value
0     name    虎子
1     name    老许
2     name    小黑
3      age    10
4      age     5
5      age     3
6   height    80
7   height    30
8   height    50
Plain text

苏南大叔:如何利用pandas的melt()方法,实现宽表转长表的操作? - melt效果
如何利用pandas的melt()方法,实现宽表转长表的操作?(图3-2)

指定主键id_vars

df_melt = pd.melt(df, id_vars=['name'])
print(df_melt)
Python

输出:

  name variable  value
0   虎子      age     10
1   老许      age      5
2   小黑      age      3
3   虎子   height     80
4   老许   height     30
5   小黑   height     50
Plain text
df_melt = pd.melt(df, id_vars=['name','age'])
print(df_melt)
Python

输出:

    name  age  variable  value
0   虎子   10   height     80
1   老许    5   height     30
2   小黑    3   height     50
Plain text

修改新列名

df_melt = pd.melt(df, id_vars=['name'], var_name='new_column_name', value_name='new_column_value')
print(df_melt)
Python

输出:

    name    new_column_name   new_column_value
0   虎子             age                10
1   老许             age                 5
2   小黑             age                 3
3   虎子          height                80
4   老许          height                30
5   小黑          height                50
Plain text

苏南大叔:如何利用pandas的melt()方法,实现宽表转长表的操作? - melt效果2
如何利用pandas的melt()方法,实现宽表转长表的操作?(图3-3)

同时指定id_varsvalue_vars

df_melt = pd.melt(df, id_vars=['name'], value_vars=['age'])
print(df_melt)
Python

输出:

    name variable  value
0   虎子      age     10
1   老许      age      5
2   小黑      age      3
Plain text
值得说明的是:本操作故意丢失了height数据。

ignore_index,忽略原有行名

不忽略的话,似乎很不妥当。

df_melt = pd.melt(df,ignore_index=False)
print(df_melt)
Python

输出:

   variable value
a1     name    虎子
a2     name    老许
a3     name    小黑
a1     foot    10
a2     foot    20
a3     foot    30
a1   height    80
a2   height    30
a3   height    50
Plain text

多重索引col_index

多重索引的情况,目前还没有涉及过,这里仅仅放个例子,以后待议。

import pandas as pd
df = pd.DataFrame({'A': {0: '苏', 1: '南'},
                   'B': {0: "大", 1: "叔"},
                   'C': {0: 666, 1: 888}})
df.columns = pd.MultiIndex.from_arrays([list('ABC'), list('DEF')], names=list('ab'))
print (df)
print (df.melt(col_level='b'))
Python

输出:

a  A  B    C
b  D  E    F
0  苏  大  666
1  南  叔  888
Plain text
   b value
0  D     苏
1  D     南
2  E     大
3  E     叔
4  F   666
5  F   888
Plain text

melt()对比.T操作

melt()作用是宽表变长表,而.T作用是行列互换。

区分主体.size旧列名旧行名
melt()id_vars的数据重复增加旧的变成数据,新列名可指定默认重置,也可以随数据增多而增多
.T不变变成行名变成列名

melt()之后可能需要的操作

melt()之后,肉眼可见的标签(行名列名)大混乱。所以,您可能需要下面的操作:

df.columns = ["col1","col2","col3"]
Python

或者:

df.index= ["row1","row2"]
Python

或者:

df.rename(
    columns={"name": "姓名", "age": "年龄", "label": "标签", "无关": "瞎写"},
    index={"a1": "第一行", "a2": "第二行"},
    inplace=True,
)
Python

参考文章:

结束语

这个melt可以丢失数据(指定value_vars),默认增多数据,行名索引也会默认被重置。总之,不是很好用。列转行的操作,仅仅是把部分列数据变成了行,和期待的行列数据互换还有较大差距。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python