Pand函数详解进阶:案例解析(第26天)

news/2024/7/8 4:27:25 标签: python, 大数据, pandas, 数据仓库, 开发语言

系列文章目录


  1. 分组对象操作
  2. 分组聚合
  3. 分组转换
  4. 分组过滤
  5. 分箱
  6. 合并操作
  7. 变形操作

文章目录

  • 系列文章目录
  • 前言
    • 1 分组对象操作
    • 2 分组聚合
      • 2.1 df分组对象直接调用聚合函数
      • 2.2 df分组对象指定聚合列
      • 2.3 df分组对象结合agg函数
    • 3 分组转换
    • 4 分组过滤
    • 5 分箱
    • 6 合并操作
      • 6.1 纵向合并
      • 6.2 横向合并
    • 7 变形操作
      • 7.1 转置
      • 7.2 stack和unstack
      • 7.3 melt
      • 7.4 pivot_table


前言

本文通过案例分析的方式详解了Pandas函数进阶常用操作。


提示:以下是本篇文章正文内容,下面案例可供参考

1 分组对象操作

  • 获取分组对象

    python">import pandas as pd
    # 加载数据集
    df = pd.read_csv('data/LJdata.csv')
    df
    # 实现分组操作是通过 groupby() 方法, 得到分组对象
    # 对区域列进行分组操作
    gs1 = df.groupby(by=['区域'])
    gs1
    type(gs1)
    # 对多列进行分组操作
    gs2 = df.groupby(by=['区域', '户型'])
    gs2
    type(gs2)
    
  • 分组对象聚合操作

    python"># gs1是分组之后的df对象, 直接调用聚合函数是对所有数值列进行聚合操作
    gs1.mean()
    # 获取分组df对象中某列数值列进行聚合操作
    # 获取df中的列, df[列名]
    print(gs1['价格'])
    gs1[['价格', '面积']]
    gs1['价格'].max()
    
  • 获取分组对象第一条或最后一条数据

    python"># 获取每组中的第一条数据
    gs2.first()
    gs1.first()
    # 获取每组中的最后一条数据
    gs2.last()
    
  • 获取分组对象分组信息

    python"># 获取分组
    gs2.grouper.result_index
    gs1.grouper.result_index
    # 获取每组数据的索引值
    gs1.groups
    
  • 获取分组对象分组数据

    python">gs2.get_group(name=('七里庄租房', '1室0厅'))
    gs2.get_group(name=('CBD租房', '2室1厅'))
    gs1['价格'].get_group(name='CBD租房')
    

2 分组聚合

2.1 df分组对象直接调用聚合函数

python"># df分组后直接调用聚合函数, 对df分组对象的所有数值列进行相同的聚合操作
# df.groupby(by=[分组列名1, 分组列名2, ...]).max/min/mean/sum/count()
# 对区域进行分组, 统计面积,价格以及看房人数列的平均值
df.groupby(by='区域').mean()
df.groupby(by=['区域']).count()

2.2 df分组对象指定聚合列

python"># df分组后对单列或多列进行聚合操作
# df.groupby(by=[列名1, 列名2, ...])[[列名]].聚合函数()  -> 一个[], 得到s对象; 两个[],得到df对象
# df.groupby(by=[列名1, 列名2, ...])[[列名1, 列名2, ...]].聚合函数()
# 对区域分组, 统计价格列的最小值, 一个[]返回s对象
df.groupby(by='区域')['价格'].min()
# 对区域分组, 统计价格列的最小值, 两个[]返回df对象
df.groupby(by='区域')[['价格']].min()
# 对区域分组, 统计价格和看房人数的求和
df.groupby(by=['区域'])[['价格', '看房人数']].sum()

2.3 df分组对象结合agg函数

  • 多个聚合函数

    python"># df分组后使用多个聚合函数
    # df.groupby(by=[列名1. 列名2, ...])[[列名1, 列名2...]].agg([聚合函数名1, 聚合函数名2, ...])
    # 对列名1进行多个聚合操作, 列名2进行多个聚合操作
    # 聚合函数名可以是pandas内置的函数名 'max', 'min';也可以是numpy中的函数名 np.mean np.sum; 直接使用python的聚合函数 max min
    import numpy as np
    # 对户型分组, 统计面积和价格列的最小值,平均值以及求和
    df.groupby(by='户型')[['面积', '价格']].agg([min, np.mean, 'sum'])
    
  • 不同列使用不同聚合函数

    python"># df分组后不同列使用不同聚合函数
    # df.groupby(by=[列名1, 列名2, ...]).agg({列名1:聚合函数名1, 列名2:聚合函数名2, ...})
    # 对户型分组, 统计面积的最大值以及价格的平均值
    df.groupby('户型').agg({'面积':max, '价格':np.mean})
    
  • 使用自定义函数

    python"># df分组后使用自定义的函数进行聚合操作  参考apply()函数
    # df.groupby(by=[列名1, 列名2, ...])[[列名1, 列名2, ...]].agg(自定义函数名, 参数2=, 参数3=)
    # 手写求平均聚合操作
    # 自定义函数最少接收一个参数, 分组后每组的数据
    def avg_func(x, arg1):
        print('x的值是->', x)
        # 平均值 = 求和值 / 个数
        # x.sum()求和
        # x.size 统计个数
        m = x.sum() / x.size
        return m + arg1
    df.groupby('户型')['价格'].agg(avg_func, arg1=10)
    
    # 手写求平均聚合操作
    # 自定义函数最少接收一个参数, 分组后每组的数据
    def avg_func(x, arg1):
        print('x的值是->', x)
        print(type(x))
        # 平均值 = 求和值 / 个数
        # sum()求和
        # size 统计个数
        m = x['价格'].sum() / x['价格'].size
        return m + arg1
    
    # 自定义函数中的x参数是df分组数据
    df.groupby('户型').agg(avg_func, arg1=10)
    
    def func(s):
        print('s的值是->', s)
        # 参数s是分组之后指定的每一列
        s_mean = s.sum() / s.size
        return s_mean 
    
    
    res = df.groupby('户型')[['价格', '看房人数']].agg(func)
    print(res)
    

3 分组转换

分组转换和分组聚合
分组转换是每组的聚合结果, 然后拼接到df后边, 不会改变df的行数; 分组之前的df有多少上数据, 分组转换之后还是多少行
分组聚合是每组的聚合结果和每组信息一同返回, 改变df的行数, 有多少分组返回多少行数据

python"># df分组之后对列进行转换(计算)操作
# df.groupby(by=[列名1, 列名2, ...])[[列名1, 列名2, ...]].transform(聚合函数)
df.groupby('户型')['价格'].agg('mean')
# 对户型分组, 统计价格列的平均值, 添加到原df后边
df.groupby('户型')['价格'].transform('mean')
# 类似于sql中的开窗函数
df['平均价格'] = df.groupby('户型')['价格'].transform('mean')
df

# transform(自定义函数名)
# 手写求平均值的函数
def func2(x, arg1):
    m = x.sum() / x.size
    return m + arg1

df.groupby(by='户型')['价格'].transform(func2, arg1=10)

4 分组过滤

python"># df.groupby(by=[列名1, 列名2, ...]).filter(lambda x: 判断条件)
# 判断条件返回True或False
# 对每组的数据结果进行判断, 留下满足条件的组数据, 删除掉不满足条件的组数据

# 根据户型分组, 保留平均价格大于1w的组数据
# x是df分组对象, 获取df中的价格列求平均值
# 判断条件是每组的价格平均值和10000比较, 不是每条数据的价格和10000比较
df.groupby(by='户型').filter(lambda x:x['价格'].mean() > 10000)

# x是df分组对象后的价格列 -> s对象
s1 = df.groupby(by='户型')['价格'].filter(lambda x: x.mean() > 10000)
s1.index
df.loc[s1.index]

5 分箱

python"># 分箱->根据df中的某列值进行分组操作
# pd.cut(x=s对象, bins=, labels=, right=, include_lowest=)
# x:分箱的列
# bins: 分箱的箱数(组数), 接受整数, 或分箱规则列表->[0, 20, 40] 0~20 20~40 40以上
# labels: 分箱的名称, 不写也会有默认值 
# right: 分箱规则列表, 默认左开右闭 True, 左闭右开 False
# include_lowest: 是否包含第一组中的起始值, 默认False不包含
# 根据价格列对数据成3组
df['价格分组'] = pd.cut(x=df['价格'], bins=3)
df
# (0, 4500]->低 (4500, 8500]->中 (8500, 210000]->高
df['价格分组2'] = pd.cut(x=df['价格'], bins=[0, 4500, 8500, 210000], labels=['低', '中', '高'])
df

6 合并操作

6.1 纵向合并

类似于sql中的 union all 操作, 将多个df纵向连接到一起

python"># 导入模块
import pandas as pd
# 创建数据集
df1 = pd.DataFrame([[1, 2, 3], [1, 10, 20], [5, 6, 7], [3, 9, 0], [8, 0, 3]], columns=['x1', 'x2', 'x3'])
df2 = pd.DataFrame([[1, 2], [1, 10], [1, 3], [4, 6], [3, 9]], index=[0, 2, 4, 6, 8], columns=['x1', 'x4'])
print(df1)
print(df2)

# df1.append(df2), 根据列名相同进行追加, 列名不同用NaN值填充
# 在df1中追加df2
# 新df会保留各自df的索引值
df1.append(df2)
df1.append(df2).reset_index(drop=True)
# ignore_index=True:重置新df的索引值
df1.append(df2, ignore_index=True)

# pd.concat([df1, df2, df3, ...])
# 纵向合并多个df, 根据列名相同进行合并, 列名不同用NaN值填充
pd.concat([df1, df2], axis=0)
# 可以通过join参数, 设置保留df之间共有的数据, 默认是outer->保留所有数据, 类似于全连接
pd.concat([df1, df2], axis=0, join='inner', ignore_index=True)

6.2 横向合并

  • concat()

    python"># pd.concat([df1, df2, df3, ...], axis=1, ignore_index=, join=)
    # 将多个df根据行索引值进行合并, 索引值相同的合并, 不相同的用NaN值填充
    pd.concat([df1, df2], axis=1)
    # ignore_index=True: 重置列名
    pd.concat([df1, df2], axis=1, ignore_index=True)
    # join='inner': 保留共有的行数据
    pd.concat([df1, df2], axis=1, join='inner')
    
  • merge()

    python"># pd.merge(left=, right=, on=, left_on=, right_on=, how=)  等同于sql的join/left join...
    # df1.merge(df2, on=, how=)
    # 根据指定的列值进行横向合并
    # on=: 两个df相同的关联列名
    # left_on/right_on: 两个df中没有相同的关联列名
    # how: 合并方式, 默认是inner, 内连接
    # 默认是内连接, how='innner'
    df1.merge(df2, on='x1')
    # left_on/right_on: 两个df中没有相同的关联列名
    pd.merge(left=df1, right=df2, left_on='x3', right_on='x1')
    # 外连接, how='outer', 关联不上的用NaN值填充
    pd.merge(df1, df2, on='x1', how='outer')
    # 左连接, how='left'
    df1.merge(df2, on='x1', how='left')
    # 右连接, how='right'
    df1.merge(df2, on='x1', how='right')
    
    
  • join()

    python"># df1.join(df2, lsuffix=, rsuffix=, how=)
    # 根据两个df的行索引值进行横向合并, 索引值不同的用NaN值填充
    # lsuffix/rsuffix: 如果横向合并df中有重名的列名,需要通过此参数设置列名的后缀
    # how: 默认是left, 保留左df的所有数据; right, outer, inner
    df1.join(df2,lsuffix='_df1',rsuffix='_df2')
    df1.join(df2,lsuffix='_df1', rsuffix='_df2', how='inner')
    df1.join(df2,lsuffix='_df1', rsuffix='_df2', how='outer')
    

7 变形操作

7.1 转置

python"># 行变列, 列变行 -> 转置
# df.T
df1.T

7.2 stack和unstack

python"># 构造示例数据集
df3 = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=['store1', 'store2', 'store3'], index=['street1', 'street2'])
df3
# stack() -> 将df表格转换成series花括号
df3.stack()
type(df3.stack())
# unstack() -> 将series花括号转换成df表格
# 对多列进行分组后, 可以通过unstack进行转换
df3.stack().unstack()

df = pd.read_csv('data/LJdata.csv')
temp = df.groupby(by=['户型', '朝向'])['价格'].mean()
temp
temp.unstack()

7.3 melt

python"># df.melt(id_vars=, value_vars=, var_name=, value_name=) 将数据实现宽变长操作
# id_vars:不变形的列名列表,  如果不指定,除了value_vars指定的变形列, 其余列都不变形(会被删除)
# value_vars: 变形的列名列表, 将指定的列名值保存到新列中, 如果不指定,除了id_vars不变形的列, 其余列都变形
# var_name: 指定变形列名保存到新列中的列名
# value_name: 指定变形列的值保存到新列的列名

df4 = pd.read_csv('data/music.csv')
df4
df4.melt(
    id_vars=['artist', 'track'],
    value_vars=['wk1', 'wk2']
)

df4.melt(
    id_vars=['artist', 'track'],
    value_vars=['wk1', 'wk2'],
    var_name='week',  # 修改存储变形列名列的列名
    value_name='score'  # 修改存储变形列值列的列名
)

# 只指定不变形的列, 剩余列需要变形
df4.melt(id_vars=['artist', 'track'])
# 只指定变形的列, 剩余列会被删除
df4.melt(value_vars=['wk1', 'wk2'])

temp.unstack().reset_index().melt(id_vars=['户型'])

7.4 pivot_table

python"># 透视表操作 -> 类似于分组聚合
# pd.pivot_table(data=, index=,columns=,values=,aggfunc=,margins=)
# index:分组列名, 作为新df的行索引值
# columns:分组列名, 作为新df的列名
# values:聚合列名
# aggfunc:聚合函数名
# margins: 是否在最后一行或一列添加求和结果

data = pd.read_csv('data/uniqlo.csv')
data.head()
# 获取销售渠道为线下的所有数据
new_data = data.query('channel=="线下"')
new_data
# 制作透视表, 获取不同城市(city->行索引)不同商品(product->列名)的销售总金额(revenue)
pd.pivot_table(data=new_data, index='city', columns='product', values='revenue', aggfunc='sum', margins=True)

# 分组聚合后unstack 等同于 透视表操作
new_data.groupby(by=['city', 'product'])[['revenue']].sum().unstack()

# index, columns, values 可以指定多列
pd.pivot_table(data=data, index=['city', 'channel'], columns=['product'], values=['revenue', 'quant'], aggfunc='sum')

pd.pivot_table(data=data, index=['city'], columns=['channel','product'], values=['revenue', 'quant'], aggfunc='sum')

在这里插入图片描述


http://www.niftyadmin.cn/n/5536350.html

相关文章

学习python常用的英语单词,有音标,有音节划分,适合英语基础差的人来入门

if [ɪf] 如果 else [els] 否则 while [waɪl] 当...的时候 for [fɔ:r] “对于”或“遍历”,适合于 break [brek] 中断 continue [kəntɪnju:] 继续 con ti nue [kən tɪ nju:] pass [pɑ:s] 通过 height [haɪt] 高度 weight [weɪt] 重量 keyword [ki:w…

Is ChatGPT a Good Personality Recognizer? A Preliminary Study?

ChatGPT是一个很好的人格识别者吗?初步调研 摘要1 介绍2 背景和相关工作3 实验3.1 数据集3.2 提示策略3.3 基线3.4 评估指标3.5 实现细节3.6 Overall Performance (RQ1)3.7 ChatGPT在人格识别上的公平性 (RQ2)3.8 ChatGPT对下游任务的人格识别能力(RQ3&a…

白骑士的C语言教学进阶篇 2.2 指针与内存管理

系列目录 上一篇:白骑士的C语言教学进阶篇 2.1 数组与字符串 在本节中,我们将深入探讨C语言中的指针与内存管理,包括指针的基础知识、指针与数组的关系,以及动态内存分配。指针是C语言中强大而灵活的工具,正确理解和使…

Mac安装AndroidStudio连接手机 客户端测试

参考文档:https://www.cnblogs.com/andy0816/p/17097760.html 环境依赖 需要java 1.8 java安装 略 下载Android Studio 地址 下载 Android Studio 和应用工具 - Android 开发者 | Android Developers 本机对应的包进行下载 安装过程 https://www.cnblogs.c…

基于深度学习的图像补全

基于深度学习的图像补全是一项利用深度学习技术来填补图像中缺失区域的研究领域。这项技术可以有效地恢复损坏或不完整的图像,使其变得完整和自然,广泛应用于图像修复、图像编辑、视频恢复和增强现实等领域。以下是关于这一领域的系统介绍: …

SpringBoot的热部署和日志体系

SpringBoot的热部署 每次修改完代码,想看效果的话,不用每次都重新启动代码,等待项目重启 这样就可以了 JDK官方提出的日志框架:Jul log4j的使用方式: (1)引入maven依赖 (2&#x…

one-api 架构解析(二)

目录 一、获取智普AI API key 二、one-api 创建渠道和配置 Token 2.1 创建渠道 2.2 配置 Token 三、访问智普AI模型 二、one-api 处理流程 2.1 URL绑定处理函数 2.2 处理流程 one-api 关于模型的访问主要分为两种,一种是符合 OpenAI API 规则,另一种是不符合 OpenAI …

JavaScript原型对象和对象原型、原型继承、原型链

目录 1. 原型对象和对象原型2. 原型继承3. 原型链 1. 原型对象和对象原型 作用: 以前通过构造函数实例化的对象,每个实例化的对象的属性和方法都是独立的,会造成内存浪费。通过prototype对象原型能实现不同实例化对象共享公用的属性和方法,减…