• Pandas数据重塑与透视


    深入浅出Pandas读书笔记

    C9 Pandas数据重塑与透视

    9.1 数据透视

    9.1.1 整理透视 df.pivot()

    要实现基础的透视操作, 可以使用df.pivot()返回按给定的索引, 列值重新组织整理后的DataFrame. df.pivot()有3个参数, 这些参数传入的值是原数据的列名, 作用分别为

    • index 作为新DataFrame的索引, 取分组去重的值, 如果不传入, 取现有索引
    • columns 作为新DataFrame的列, 取去重的值, 当列和索引的组合有多个值的时候会报错(需要使用聚合函数, pivot只负责重塑, 没有聚合功能), 需要使用df.pivot_table()进行操作
    • values 作为新DataFrame()的值, 如果指定多个, 会形成多层索引, 如果不指定, 会默认人为所有剩余的列

    9.1.2 整理透视操作

    df = pd.DataFrame({"A": ['a1', 'a1', 'a2', 'a3', 'a3', 'a3'],
                       'B': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3'],
                       'C': ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'],
                       'D': ['d1', 'd2', 'd3', 'd4', 'd5', 'd6'],
                      })
    df.pivot(index='A', columns='B', values='C') # A与B没有重复值, 将A列去重作为索引, B列去重作为列, 取C的内容作为具体的数据值
    '''
    B	b1	b2	b3
    A			
    a1	c1	c2	NaN
    a2	NaN	NaN	c3
    a3	c4	c5	c6
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    9.1.3 聚合透视

    df.pivot()只是对原数据的结构, 显示做了变换, 在实现业务中, 往往还需要在数据透视过程中对值进行计算, 这时候就要用到pd.pivot_table()
    pd.pivot_table()有以下几个关键参数

    • data
    • index
    • values 要聚合的值
    • columns 要聚合的列
    • aggfunc 聚合函数
    • fill_value
    • margins 是否增加汇总行列

    9.1.4 聚合透视操作

    df = pd.DataFrame({"A": ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
                       'B': ['b2', 'b2', 'b1', 'b1', 'b1', 'b1'],
                       'C': ['c1', 'c1', 'c2', 'c2', 'c1', 'c1'],
                       'D': [1, 2, 3, 4, 5, 6],
                      })
    # 如果对以上数据进行以A为索引, 以B为列的透视df.pivot(), 会报错, 因为索引和列组合后有重复数据, 涉及到聚合操作, 需要使用pd.pivot_table()
    df.pivot_table(index='A', columns='B', values='D') # 默认求mean
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    9.1.5 聚合透视高级操作

    df.pivot_table(index=['A', 'B'], columns='C', values='D', aggfunc=np.sum, fill_value=0, margins=True)
    # 使用多个计算方法
    df.pivot_table(index=['A', 'B'], columns='C', values='D', aggfunc=[np.mean, np.sum])
    # 为每一列指定不同的计算方法
    df = pd.DataFrame({
        'A': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
        'B': ['b2', 'b2', 'b1', 'b1', 'b1', 'b1'],
        'C': ['c1', 'c1', 'c2', 'c2', 'c1', 'c1'],
        'D': [1, 2, 3, 4, 5, 6],
        'E': [9, 8, 7, 6, 5, 4]
    })
    df.pivot_table(index=['A', 'B'], columns='C', aggfunc={'D': np.mean, 'E': np.sum})
    df.pivot_table(index=['A', 'B'], columns='C', aggfunc={'D': [np.mean], 'E': np.sum}) # 在aggfunc内的函数中加入[], 在现实中会把函数名显示出
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    9.2 数据堆叠

    9.2.1 理解堆叠

    堆叠stack的过程表示将数据列的所有数据表全部旋转到列上
    解堆unstack的过程表示将在行上的索引旋转到列上

    • 堆叠: 透视某个级别的列标签, 返回带有索引的DataFrame, 该索引带有一个新的行标签, 这个新标签在原有索引的左右边
    • 解堆: 将航索引的某个级别透视到列轴, 从而生成具有新的最里面的列标签级别的重构的DataFrame
      堆叠过程将数据集的列转行, 解堆过程为行转列

    9.2.2 堆叠操作 df.stack()

    df = pd.DataFrame({
        'A': ['a1', 'a1', 'a2', 'a2'],
        'B': ['b1', 'b2', 'b1', 'b2'],
        'C': [1, 2, 3, 4],
        'D': [5, 6, 7, 8],
        'E': [5, 6, 7, 8]
    })
    df.set_index(['A', 'B'], inplace=True)
    df.stack()
    '''
    A   B    
    a1  b1  C    1
            D    5
            E    5
        b2  C    2
            D    6
            E    6
    a2  b1  C    3
            D    7
            E    7
        b2  C    4
            D    8
            E    8
    dtype: int64
    '''
    type(df.stack()) # pandas.core.series.Series
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    9.2.3 解堆操作 df.unstack()

    df.stack().unstack()
    '''
    		C	D	E
    A	B			
    a1	b1	1	5	5
    b2	2	6	6
    a2	b1	3	7	7
    b2	4	8	8
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    9.3 交叉表 crosstab

    交叉表就是将两列或多列中不重复的元素组成一个新的DataFrame, 新数据的行和列交叉部分的值为其组合在原数据中的数量

    9.3.1 基本语法

    pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, 
                margins_name: str='All', dropna: bool=True, normalize=False
    )
    
    • 1
    • 2
    • 3

    参数说明如下

    • index
    • columns
    • values
    • aggfunc
    • rownames 新行名
    • colnames 新列名
    • margins
    • normalize 布尔值, {‘all’, ‘index’ ‘columns’} 或 {0, 1}, 默认值为False, 通过将所有值除以值的总和进行归一化

    9.3.2 生成交叉表

    df = pd.DataFrame({
        'A': ['a1', 'a1', 'a2', 'a2', 'a1'],
        'B': ['b2', 'b1', 'b2', 'b2', 'b1'],
        'C': [1, 2, 3, 4, 5],
    })
    pd.crosstab(df.A, df.B)
    '''
    B	b1	b2
    A		
    a1	2	1
    a2	0	2
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    9.3.3 归一化

    # 整体中的占比
    pd.crosstab(df.A, df.B, normalize=True)
    # 在列中的占比
    pd.crosstab(df.A, df.B, normalize='columns')
    
    • 1
    • 2
    • 3
    • 4

    9.3.4 指定聚合方法

    9.3.5 汇总

    9.4 数据转置 df.T

    9.4.1 数据转置

    9.4.2 转置操作

    9.4.3 类型变化

    9.4.4 轴交换 df.swapaxes()

    9.5 数据融合 df.melt()

    9.5.1 基本语法

    pd.melt(frame, id_vars=None, value_vars=None, var_name='variable', value_name='value', col_level=None)
    )
    
    • 1
    • 2

    参数说明

    • id_vars: 需要作为表示的列
    • value_vars: 需要堆起来的列, 如果不指定, 则使用未设置为id_vars的所有列
    • var_name
    • value_name
    • col_level

    9.5.2 融合操作

    df = pd.DataFrame({
        'A': ['a1', 'a2', 'a3', 'a4', 'a5'],
        'B': ['b1', 'b2', 'b3', 'b4', 'b5'],
        'C': [1, 2, 3, 4, 5]
    })
    df.melt()
    '''
    variable	value
    0	A	a1
    1	A	a2
    2	A	a3
    3	A	a4
    4	A	a5
    5	B	b1
    6	B	b2
    7	B	b3
    8	B	b4
    9	B	b5
    10	C	1
    11	C	2
    12	C	3
    13	C	4
    14	C	5
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    9.5.3 标识和值

    9.5.4 指定名称

    df.melt(id_vars=['A'], value_vars=['B'], var_name='Blabel', value_name='B_value')
    
    • 1

    9.6 虚拟变量 pd.get_dummies() -> one-hot编

    虚拟变量(Dummy Variable)又称虚设变量, 名义变量或哑变量, 是一个用来反映质的属性的人工变量, 是量化了的自变量, 通常取值为0或1, 常被用于one-hot特征提取

    9.6.1 语法结构

    pd.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
    
    • 1

    9.6.2 生成虚拟变量

    df = pd.DataFrame({
        'a': list('abcd'), 
        'b': list('fehg'), 
        'a1': range(4), 
        'b1': range(4, 8)})
    # 对a进行one-hot操作
    pd.get_dummies(df.a)
    '''
    a	b	c	d
    0	1	0	0	0
    1	0	1	0	0
    2	0	0	1	0
    3	0	0	0	1
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    9.6.3 列前缀

    9.6.4 从DataFrame生成

    # 保持其他列的情况下, 对a进行one-hot
    pd.get_dummies(df, columns=['a']) # 只对a进行one-hot处理
    '''
    	b	a1	b1	a_a	a_b	a_c	a_d
    0	f	0	4	1	0	0	0
    1	e	1	5	0	1	0	0
    2	h	2	6	0	0	1	0
    3	g	3	7	0	0	0	1
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    9.7 因子化

    因子化是指讲一个存在大量重复值的一维数据解析成枚举值的过程, 这样可以方便我们进行分辨. factorize既可以用作顶层函数pd.factorize(), 也可以用作Series.factorize()Index.factorize()方法

    9.7.1 基本方法

    对数据因子化后返回两个值, 一个是因子化后的编码列表, 另一个是原数据的去重值列表

    data = ['b', 'b', 'a', 'c', 'b']
    pd.factorize(data) # 返回编码, 和去重置
    '''
    (array([0, 0, 1, 2, 0], dtype=int64), array(['b', 'a', 'c'], dtype=object))
    '''
    # 
    cat = pd.Series(['a', 'a', 'c'])
    codes, uniques = pd.factorize(cat)
    codes, uniques
    '''
    (array([0, 0, 1], dtype=int64), Index(['a', 'c'], dtype='object'))
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    9.7.2 排序

    codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'], sort=True)
    codes, uniques
    '''
    (array([1, 1, 0, 2, 1], dtype=int64), array(['a', 'b', 'c'], dtype=object))
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5

    9.7.3 缺失值

    # 缺失值不会出现在唯一值列表中, 在编码中将为-1
    codes, uniques = pd.factorize(['b', None, 'a', 'c', 'b'], sort=True)
    codes, uniques
    '''
    (array([ 1, -1,  0,  2,  1], dtype=int64),
     array(['a', 'b', 'c'], dtype=object))
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    9.7.4 枚举类型

    Pandas的枚举类型数据Categorical也可以使用此方法

    小结

    因子化方法pd.factorize()做了两件事, 一是对数据进行数字编码, 二是对数据进行去重, 在大序列数据中, 因子化能帮助我们抽取数据特征, 将数据变成类别数据再进行分析.

    9.8 爆炸列表

    将类似列表每个元素转换为一行, 索引值是相同的

    9.8.1 基本功能

    s = pd.Series([[1, 2, 3], 'foo', [], [3, 4]])
    s.explode()
    '''
    0      1
    0      2
    0      3
    1    foo
    2    NaN
    3      3
    3      4
    dtype: object
    '''
    # 每行列表中的元素都独占了一行, 而索引保持不变, 空列表变成了NaN
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    9.8.2 DataFrame的爆炸

    df = pd.DataFrame({'A': [[1, 2, 3], 'foo', [], [3, 4]], 'B': range(4)})
    df.explode('A')
    '''
    A	B
    0	1	0
    0	2	0
    0	3	0
    1	foo	1
    2	NaN	2
    3	3	3
    3	4	3
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    9.8.3 非列表格式

    df = pd.DataFrame([{'var1': 'a, b, c', 'var2': 1}, {'var1': 'd, e, f', 'var2': 2}])
    '''
    var1	var2
    0	a, b, c	1
    1	d, e, f	2
    '''
    df.assign(var1=df.var1.str.split(',')).explode('var1')
    '''
    	var1	var2
    0	a	1
    0	b	1
    0	c	1
    1	d	2
    1	e	2
    1	f	2
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    真正“搞”懂HTTP协议04之搞起来
    Win7显示屏幕亮度在哪里可以调节
    Vue 404处理与钩子函数
    spring整合JdbcTemplate进行数据库操作
    2022年最新海南机动车签字授权人模拟考试及答案
    学校食堂明厨亮灶 yolov8
    【数据结构与算法】之深入解析“摘樱桃II”的求解思路与算法示例
    MCU常见通信总线串讲(二)—— RS232和RS485
    研究了11种实时聊天软件,我发现都具备这些功能…
    Notepad++下载安装
  • 原文地址:https://blog.csdn.net/zhaoleiedu/article/details/127816056