python–pandas长宽数据转换

长型数据(long format dataframe)与宽型数据(wide format dataframe)是两种形式的数据框,在数据分析中高频出现,在数据处理过程中,
常常需要在两者之间相互转换。本文基于pandas,介绍长型数据与宽型数据的相互转换操作。

  • python3.9
  • win10 64bit
  • pandas==1.2.1

宽转长

在pandas中,宽型转长型数据有 meltwide_to_long两种方法。

melt方法叫做数据融合,是dataFrame拥有的方法,使用较为频繁。参数解释如下:

DataFrame.melt(id_vars=None, value_vars=None, var_name=None, value_name=’value’, col_level=None, ignore_index=True)

  • id_vars:[tuple, list, ndarray],列中识别符变量,不参与融合。
  • value_vars:[tuple, list, ndarray],列中融合变量,默认全部融合。
  • var_name:[scalar],融合后变量名字,默认variable。
  • value_name:[scalar],融合后值名字,默认value。
  • col_level:[int, str],多重列索引时选择列。
  • ignore_index:[bool],融合后索引是否重新排序,默认True。
import pandas as pd
pd.set_option('display.notebook_repr_html',False)

w_df = pd.DataFrame({'A': [1,2,3],
                   'B': [4,5,6],
                   'C': [7,8,9]})
w_df
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9
  • 当不传入任何参数时,默认会融合全部的列。

w_df.melt()
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
6        C      7
7        C      8
8        C      9
  • 设置 id_vars参数,选择部分列作为识别符不参与融合,剩余的列将全部融合。

w_df.melt(id_vars=['A'])
   A variable  value
0  1        B      4
1  2        B      5
2  3        B      6
3  1        C      7
4  2        C      8
5  3        C      9

w_df.melt(id_vars=['A','B'])
   A  B variable  value
0  1  4        C      7
1  2  5        C      8
2  3  6        C      9
  • 设置 value_vars参数,选择部分列作为融合列。

注意剩余的列不会自动作为标识符列。


w_df.melt(value_vars=['A'])
  variable  value
0        A      1
1        A      2
2        A      3

w_df.melt(value_vars=['A','B'])
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
  • 设置 var_name(默认variable), value_name(默认value)参数,为融合的变量与值设置名字。

w_df.melt(var_name='code',value_name='count')
  code  count
0    A      1
1    A      2
2    A      3
3    B      4
4    B      5
5    B      6
6    C      7
7    C      8
8    C      9
  • 设置 ignore_index=False可以保留原数据的索引。
w_df.melt(ignore_index=False)
  variable  value
0        A      1
1        A      2
2        A      3
0        B      4
1        B      5
2        B      6
0        C      7
1        C      8
2        C      9
  • 设置 col_level参数,可以选择多重列索引数据来融合数据。

mi_w_df=w_df.copy()
mi_w_df.columns=[list('ABC'),list('DEF')]
mi_w_df
   A  B  C
   D  E  F
0  1  4  7
1  2  5  8
2  3  6  9

mi_w_df.melt(col_level=0)
  variable  value
0        A      1
1        A      2
2        A      3
3        B      4
4        B      5
5        B      6
6        C      7
7        C      8
8        C      9

mi_w_df.melt(col_level=1)
  variable  value
0        D      1
1        D      2
2        D      3
3        E      4
4        E      5
5        E      6
6        F      7
7        F      8
8        F      9

wide_to_long函数是pandas自带的,是对melt的一种补充,在特殊的宽转长情况下更适用。

pandas.wide_to_long(df, stubnames, i, j, sep=”, suffix=’\d+’)

  • df:[pd.dataframe],宽型数据框
  • stubnames:[str,list-like],列名中的存根名字
  • i:[str,list-like],列中的索引变量
  • j:[str],后缀的重命名
  • sep:[str,default “”],存根名与后缀之间的分隔符
  • suffix:[str,default “\d+”],后缀

s_df = pd.DataFrame({"A1970" : [1,33,3],
                   "B1980" : [3,5,7],
                   "A1980" : [13,15,17],
                   "B1970" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
s_df
   A1970  B1980  A1980  B1970  x  y
0      1      3     13      6  1  4
1     33      5     15      8  2  5
2      3      7     17     14  3  6

在数据中, A1970, B1980, A1980, B1970这几列名字具有相同的结构,如果需要将它们分开,就可以用 long_to_wide函数。


pd.wide_to_long(s_df,stubnames=['A','B'],j='year',i='x')
        y   A   B
x year
1 1970  4   1   6
  1980  4  13   3
2 1970  5  33   8
  1980  5  15   5
3 1970  6   3  14
  1980  6  17   7
  • 设置 stubnames,函数会根据设置的字符去数据列中匹配目标列,然后转换为长数据

pd.wide_to_long(s_df,stubnames=['A',],j='year',i='x')
        B1970  y  B1980   A
x year
1 1970      6  4      3   1
2 1970      8  5      5  33
3 1970     14  6      7   3
1 1980      6  4      3  13
2 1980      8  5      5  15
3 1980     14  6      7  17

如果 stubnames参数设置的字符在原数据框的列中无法找到,则返回空数据框。


pd.wide_to_long(s_df,stubnames=['C',],j='year',i='x')
Empty DataFrame
Columns: [B1970, y, A1980, B1980, A1970, C]
Index: []
  • 参数 i可以设置为多列,返回多个索引。

pd.wide_to_long(s_df,stubnames=['A','B'],j='year',i=['x','y'])
           A   B
x y year
1 4 1970   1   6
    1980  13   3
2 5 1970  33   8
    1980  15   5
3 6 1970   3  14
    1980  17   7
  • 参数 sep表示分隔符,默认 "",可以根据实际情况设置。

sep_df = pd.DataFrame({"A-1970" : [1,33,3],
                   "B-1980" : [3,5,7],
                   "A-1980" : [13,15,17],
                   "B-1970" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
sep_df
   A-1970  B-1980  A-1980  B-1970  x  y
0       1       3      13       6  1  4
1      33       5      15       8  2  5
2       3       7      17      14  3  6

数据中列名的分隔符为 -,则转换的时候需要设置 sep='-'


pd.wide_to_long(sep_df,stubnames=['A','B'],j='year',i='x',sep='-')
        y   A   B
x year
1 1970  4   1   6
  1980  4  13   3
2 1970  5  33   8
  1980  5  15   5
3 1970  6   3  14
  1980  6  17   7
  • 参数 suffix表示后缀,默认是 "\d+",是 正则表达式,表示匹配数字,可以根据实际情况替换。

suf_df = pd.DataFrame({"Aone" : [1,33,3],
                   "Btwo" : [3,5,7],
                   "Atwo" : [13,15,17],
                   "Bone" : [6,8,14],
                   "x"     : [1,2,3],
                   "y"     : [4,5,6]})
suf_df
   Aone  Btwo  Atwo  Bone  x  y
0     1     3    13     6  1  4
1    33     5    15     8  2  5
2     3     7    17    14  3  6

pd.wide_to_long(suf_df,stubnames=['A','B'],j='year',i='x',suffix='(one|two)')
        y   A   B
x year
1 one   4   1   6
  two   4  13   3
2 one   5  33   8
  two   5  15   5
3 one   6   3  14
  two   6  17   7

长转宽

长型数据转为宽型数据可以通过透视的功能实现,类似于excel中的透视表功能。在pandas中用 pivot方法实现。

DataFrame.pivot(index=None, columns=None, values=None)

  • index:[str ,object ,a list of str],透视的索引
  • columns:[str ,object ,a list of str],透视的列
  • values:[str, object ,a list of the previous],透视的值

l_df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two','two'],
                   'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'cat':['alpha','alpha','alpha','beta','beta','beta'],
                   'baz': [1, 2, 3, 4, 5, 6],
                   'zoo': [4, 6, 8, 1, 2, 9]})
l_df
   foo bar    cat  baz  zoo
0  one   A  alpha    1    4
1  one   B  alpha    2    6
2  one   C  alpha    3    8
3  two   A   beta    4    1
4  two   B   beta    5    2
5  two   C   beta    6    9

选择 foo列作为透视后的索引, bar列作为透视的列,里面的元素会展开成新数据框的列, baz作为透视的值,填充在新数据框中。


l_df.pivot(index='foo',columns='bar',values='baz')
bar  A  B  C
foo
one  1  2  3
two  4  5  6
  • 设置 index为多个列名,透视表将具有多个行索引。

l_df.pivot(index=['foo','bar'],columns='cat',values='baz')
cat      alpha  beta
foo bar
one A      1.0   NaN
    B      2.0   NaN
    C      3.0   NaN
two A      NaN   4.0
    B      NaN   5.0
    C      NaN   6.0
  • 设置 columns为多个列名,透视表将具有多个列索引。

l_df.pivot(index='foo',columns=['bar','cat'],values='baz')
bar     A     B     C    A    B    C
cat alpha alpha alpha beta beta beta
foo
one   1.0   2.0   3.0  NaN  NaN  NaN
two   NaN   NaN   NaN  4.0  5.0  6.0
  • 设置 values为多个列名。
l_df.pivot(index='foo',columns='bar',values=['baz','zoo'])

    baz       zoo
bar   A  B  C   A  B  C
foo
one   1  2  3   4  6  8
two   4  5  6   1  2  9

Original: https://blog.csdn.net/jhr112/article/details/115914407
Author: FTDdata
Title: python–pandas长宽数据转换

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/739401/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Pycharm创建Django项目示例

    一、Pycharm安装Django框架 二、新建Django项目 1 、 m anage.py是个管理角色,拥有的功能包括: (1)创建app: python manage.py …

    Python 2023年8月6日
    035
  • python读取多个文件夹_在python中如何从不同的文件夹读取多个文件

    我在不同的文件夹中有年度数据文件。每个文件包含从1月1日到12月31日的每日数据。数据文件名类似于AS060419.67,其中最后四位代表年份,即1967年,0604是文件夹名。在…

    Python 2023年8月8日
    056
  • Pandas、Excel实现 Pytest 数据驱动

    引言 前面分享的推文 自动化测试必会—数据驱动DDT 介绍过 unittest 框架中操作 JSON 和 YAML 文件实现数据驱动。那么在 pytest 中,又该如何实现呢? P…

    Python 2023年9月11日
    048
  • python常用标准库(os系统模块、shutil文件操作模块)

    常用的标准库 系统模块 import os 系统模块用于对系统进行操作。 常用方法 os模块的常用方法有数十种之多,本文中只选出最常用的几种,其余的还有权限操作、文件的删除创建等详…

    Python 2023年11月2日
    028
  • 区块链开发完整指南。如何开发一款区块链项目?

    区块链开发完整指南 如今,区块链已成为主流技术,以其去中心化的特性为应用程序提供动力。区块链技术的日益普及和有前途的内在特性已经在人们之间建立了信任,因此它已在全球多个行业中得到广…

    Python 2023年9月27日
    035
  • Python爬虫进阶(七):Scrapy初步

    Scrapy 1 定义 2 特点 3 官方文档 #4 scrapy项目的工作流程 Scrapy中的术语 1 调度器(Scheduler) 2 下载器(Downloader) 3 实…

    Python 2023年10月3日
    050
  • 介绍一下python有趣的库-tqdm

    Tqdm 是 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息用法:tqdm(iterator)方法1: import time from tqdm im…

    Python 2023年6月9日
    053
  • conda的使用(速查手册)

    个人云端速查手册,欢迎补充! python环境管理工具,可同时管理不同Python版本的运行环境,可在不同环境之间来回切换。 conda命令 0.更新&安装 conda i…

    Python 2023年9月8日
    032
  • halcon如何识别硬币?

    halcon如何识别硬币? 前言 最近一直在学习halcon,在此做了一个案例,分享给大家,效果图如下: 1.思路分析 通过观察,发现1元,5角,1角,它们在 面值的文字描述不一样…

    Python 2023年10月14日
    049
  • Python爬虫-scrapy基本使用

    scrapy是什么? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。 scrapy项目的创建…

    Python 2023年10月1日
    050
  • Django博文数据可视化、simple-ui优化、导入导出插件

    Django博文数据可视化、simple-ui优化、导入导出插件 今日任务 django博客admin优化 导入导出插件 DRF的action装饰器 博文数据可视化 昨日未解决问题…

    Python 2023年8月6日
    059
  • pandas 第三章 索引

    import numpy as np import pandas as pd 一、索引器 列索引是最常见的索引形式,一般通过 []来实现。通过 [列&…

    Python 2023年8月21日
    041
  • scrapy进行分布式爬虫

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

    Python 2023年10月4日
    034
  • 【Python】绘制空气质量日历图

    Original: https://www.cnblogs.com/123456feng/p/16112309.htmlAuthor: 蚂蚁ailingTitle: 【Python…

    Python 2023年11月9日
    022
  • Python文件操作

    一、open 函数 python 提供内置函数 open()实现对文件的操作。python 对文本文件和二进制文件采用统一的操作步骤,和把大象放冰箱里的一样分三步,”打…

    Python 2023年8月1日
    057
  • Python中numpy数据分析库知识点总结

    Python中numpy数据分析库知识点总结 * – 一、numpy读取数据 – 二、对已读取数据的处理 – + 2.1 转置 + * ①第一种…

    Python 2023年8月30日
    033
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球