百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

[Python]Pandas高级操作:多级索引、窗口函数、数据透视表等

ztj100 2025-02-18 14:24 9 浏览 0 评论

在数据处理和分析中,pandas库提供了强大的功能,支持从简单到复杂的数据操作。本文将介绍一些pandas的高级操作,包括多级索引(MultiIndex)、窗口函数(Window Functions)、数据透视表与复杂聚合、数据合并与连接、高级数据变换以及时间序列数据的高级处理。


1. 多级索引(MultiIndex)


多级索引(MultiIndex)是pandas中一个非常有用的功能,它允许我们在一个轴上拥有多个(两个以上)索引级别。这对于处理具有层次结构的数据非常有用,例如,我们可以同时按厂商和产品对销售数据进行分组。


import pandas as pd
import numpy as np

# 创建多重索引的列表
arrays = [
    ['华为', '华为', '苹果', '苹果', '小米', '小米', '三星', '三星'],      # 厂商级别索引
    ['手机', '笔记本', '手机', '笔记本', '手机', '笔记本', '手机', '笔记本']  # 产品级别索引
]
# 从列表创建多重索引,并给索引级别命名
index = pd.MultiIndex.from_arrays(arrays, names=['厂商', '产品'])
# 创建数据框,使用多重索引作为行索引
# 假设华为的销量和销售额最高,其次是苹果,然后是小米,最后是三星
# 数据单位为“万”
sales_data = [1000, 800, 750, 600, 500, 400, 300, 200]  # 销量(单位:万)
revenue_data = [5000, 4000, 3750, 3000, 2500, 2000, 1500, 1000]  # 销售额(单位:万)
df = pd.DataFrame({'销量(万)': sales_data, '销售额(万)': revenue_data}, index=index)

print("原始数据框:")
print(df)

# 选择厂商为'华为'和产品为'手机'的数据
filtered_df = df.loc[('华为', '手机')]
print("\n选择厂商为'华为'和产品为'手机'的数据:")
print(filtered_df)

# 重塑数据框,将产品级别索引作为列
reshaped_df = df.unstack(level='产品')
print("\n重塑数据框,将产品级别索引作为列:")
print(reshaped_df)


运行结果:


原始数据框:
        销量(万)  销售额(万)
厂商 产品                
华为 手机    1000    5000
   笔记本    800    4000
苹果 手机     750    3750
   笔记本    600    3000
小米 手机     500    2500
   笔记本    400    2000
三星 手机     300    1500
   笔记本    200    1000

选择厂商为'华为'和产品为'手机'的数据:
销量(万)     1000
销售额(万)    5000
Name: (华为, 手机), dtype: int64

重塑数据框,将产品级别索引作为列:
   销量(万)      销售额(万)      
产品    手机  笔记本     手机   笔记本
厂商                        
三星   300  200   1500  1000
华为  1000  800   5000  4000
小米   500  400   2500  2000
苹果   750  600   3750  3000



2. 窗口函数(Window Functions)


窗口函数(Window Functions)是一种非常有用的数据分析工具,特别是在处理时间序列数据时。它们允许我们对数据进行滚动计算,例如计算移动平均。


import pandas as pd
# 创建示例数据框
dates = pd.date_range('2023-01-01', periods=10)
df = pd.DataFrame({'日期': dates, '数值': np.random.randn(10)})

# 设置日期列为索引
df.set_index('日期', inplace=True)

# 计算移动平均
df['移动平均'] = df['数值'].rolling(window=3).mean()
print(df)


运行结果:


                  数值      移动平均
日期                            
2023-01-01 -0.695894       NaN
2023-01-02 -0.335897       NaN
2023-01-03 -0.402681 -0.478157
2023-01-04 -0.081337 -0.273305
2023-01-05  0.178860 -0.101719
2023-01-06 -1.256918 -0.386465
2023-01-07 -0.756770 -0.611609
2023-01-08 -1.254951 -1.089546
2023-01-09  1.600473 -0.137083
2023-01-10 -0.343765  0.000586



3. 数据透视表与复杂聚合


数据透视表(Pivot Tables)是pandas中另一个强大的功能,它允许我们快速地对数据进行分组、聚合和重塑。我们还可以使用自定义聚合函数来创建更复杂的数据透视表。


# 创建示例数据框
data = {'类别': ['A', 'A', 'B', 'B'],
        '子类别': ['X', 'Y', 'X', 'Y'],
        '数值': [10, 20, 30, 40]}
df = pd.DataFrame(data)

# 自定义聚合函数
def custom_agg(x):
    return np.sum(x) / np.mean(x)

# 创建数据透视表
pivot_df = df.pivot_table(values='数值', index='类别', columns='子类别', aggfunc=custom_agg)
print(pivot_df)


4. 数据合并与连接


在数据分析中,我们经常需要合并来自不同来源的数据。pandas提供了多种数据合并和连接的方法,可以轻松处理重复列和缺失值。


import pandas as pd

# 创建多个示例数据框
df1 = pd.DataFrame({'产品类别': ['手机', '笔记本', '耳机'],
                    '品牌': ['华为', '苹果', '小米'],
                    '销量': [1000, 800, 750]})
df2 = pd.DataFrame({'产品类别': ['笔记本', '耳机', '电视'],
                    '品牌': ['苹果', '小米', '三星'],
                    '销售额': [5000, 4000, 3000]})

# 合并数据框
merged_df = df1.merge(df2, on=['产品类别', '品牌'], how='outer')
print(merged_df)



运行结果:


   产品类别 品牌  销量  销售额
0   手机   华为   1000     NaN
1   笔记本  苹果    800  5000.0
2   耳机   小米    750  4000.0
3   电视   三星    NaN  3000.0



# 详细解释代码段 

merged_df = df1.merge(df2, on=['产品类别', '品牌'], how='outer') 

'''
1、df1.merge(df2, on=['产品类别', '品牌'], how='outer'):

df1 和 df2 是两个 pandas 数据框(DataFrame)。
merge 函数用于将两个或多个数据框根据一个或多个键进行合并。
on=['产品类别', '品牌']:指定用于合并的键。这里使用的是多键合并,意味着数据框将基于“产品类别”和“品牌”两个列进行合并。
how='outer':指定合并的方式。'outer' 表示外连接(Outer Join),在这种连接方式下,结果将包含左数据框(df1)和右数据框(df2)的所有行,即使在另一个数据框中没有匹配的行。

2、merged_df = ...:
merged_df 是合并操作的结果,它是一个新的数据框,包含了原始数据框的合并结果。
    

当运行这段代码时,merged_df 将包含所有在 df1 和 df2 中具有匹配“产品类别”和“品牌”的行。对于在任一数据框中没有匹配的键,结果数据框中将包含缺失值(NaN)。这种合并方式特别适用于需要将来自不同来源的数据整合在一起的场景,比如将销售数据和库存数据合并,以便进行全面的业务分析。
'''


5. 高级数据变换


pandas的apply函数允许我们对数据框的每一行或每一列应用自定义函数,从而实现高级数据变换。


import pandas as pd

# 创建示例数据框
data = {'A': [1, 2, 3, 4],
        'B': [10, 20, 30, 40]}
df = pd.DataFrame(data)

# 定义复杂变换函数
def complex_transformation(row):
    return pd.Series({
        'A加B': row['A'] + row['B'],
        'A乘B': row['A'] * row['B'],
        'A除以B': row['A'] / row['B'] if row['B'] != 0 else np.nan
    })

# 应用复杂变换函数
transformed_df = df.apply(complex_transformation, axis=1)
# 将变换结果和原df合并输出
merged_df=pd.merge(df,transformed_df,left_index=True,right_index=True,how='left')
print(merged_df)



运行结果:


   A   B   A加B    A乘B  A除以B
0  1  10  11.0   10.0   0.1
1  2  20  22.0   40.0   0.1
2  3  30  33.0   90.0   0.1
3  4  40  44.0  160.0   0.1


【更高效的方案,特别是数据量大的情况】
上面代码是用一个复杂的变换函数来生成新的列。这个函数对每一行数据执行多种计算,包括加法、乘法和除法。为了优化这段代码,我们可以考虑以下几个方面:


  1. 避免使用apply函数apply函数在处理大型数据集时可能会很慢,因为它会对每一行数据调用Python函数。使用Pandas的内建函数和向量操作会更高效。
  2. 直接使用向量操作:Pandas支持向量操作,这意味着您可以对整个列进行操作,而不需要逐行处理。这通常比使用apply函数快得多。
  3. 简化函数逻辑:如果可以的话,简化函数逻辑可以使其更容易理解和维护。


基于这些原则,我们可以重写代码如下所示:


import pandas as pd

# 创建示例数据框
data = {'A': [1, 2, 3, 4],
        'B': [10, 20, 30, 40]}
df = pd.DataFrame(data)

# 使用向量操作进行计算
df['A加B'] = df['A'] + df['B']
df['A乘B'] = df['A'] * df['B']
df['A除以B'] = df['A'] / df['B']
df['A除以B'].fillna(value=np.nan, inplace=True)  # 用NaN替换除以0的情况

print(df)


这段代码使用了Pandas的向量操作来计算新列,而不是对每一行应用一个函数。这种方法通常更快,尤其是在处理大型数据集时。同时,我们使用fillna函数来处理除以0的情况,将结果替换为NaN,运行结果一致。


6. 时间序列数据的高级处理


时间序列数据是数据分析中的一个重要方面。在处理时间序列数据时,我们经常需要处理缺失值和时间相关的数据。


import pandas as pd
import numpy as np

# 创建日期范围和数值
dates = pd.date_range('2023-01-01', periods=10)
values = [1, np.nan, 5, np.nan, 8, 13, np.nan, 24, np.nan, 40]
df = pd.DataFrame({'日期': dates, '数值': values})

# 设置日期列为索引
df.set_index('日期', inplace=True)

# 填充缺失值
df['插值填充后数值'] = df['数值'].interpolate(method='time')
print(df)

import matplotlib.pyplot as plt

# 绘图显示插值情况
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['数值'], label='Original Value', marker='o',markersize=20)
plt.plot(df.index, df['插值填充后数值'], label='Interpolated Value', marker='o')
plt.title('Interpolation Results')
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
plt.grid(True)
plt.show()

运行结果(插值结果):


              数值  插值填充后数值
日期                     
2023-01-01   1.0    1.0
2023-01-02   NaN    3.0
2023-01-03   5.0    5.0
2023-01-04   NaN    6.5
2023-01-05   8.0    8.0
2023-01-06  13.0   13.0
2023-01-07   NaN   18.5
2023-01-08  24.0   24.0
2023-01-09   NaN   32.0
2023-01-10  40.0   40.0



通过这些示例,我们可以看到pandas的强大功能,它不仅支持基本的表格操作,还支持复杂的数据分析和数据处理任务。这些高级操作是数据科学家和数据分析师在实际工作中常用的工具,能够帮助他们更有效地处理和分析数据。

相关推荐

告别手动操作:一键多工作表合并的实用方法

通常情况下,我们需要将同一工作簿内不同工作表中的数据进行合并处理。如何快速有效地完成这些数据的整合呢?这主要取决于需要合并的源数据的结构。...

【MySQL技术专题】「优化技术系列」常用SQL的优化方案和技术思路

概述前面我们介绍了MySQL中怎么样通过索引来优化查询。日常开发中,除了使用查询外,我们还会使用一些其他的常用SQL,比如INSERT、GROUPBY等。对于这些SQL语句,我们该怎么样进行优化呢...

9.7寸视网膜屏原道M9i双系统安装教程

泡泡网平板电脑频道4月17日原道M9i采用Win8安卓双系统,对于喜欢折腾的朋友来说,刷机成了一件难事,那么原道M9i如何刷机呢?下面通过详细地图文,介绍原道M9i的刷机操作过程,在刷机的过程中,要...

如何做好分布式任务调度——Scheduler 的一些探索

作者:张宇轩,章逸,曾丹初识Scheduler找准定位:分布式任务调度平台...

mysqldump备份操作大全及相关参数详解

mysqldump简介mysqldump是用于转储MySQL数据库的实用程序,通常我们用来迁移和备份数据库;它自带的功能参数非常多,文中列举出几乎所有常用的导出操作方法,在文章末尾将所有的参数详细说明...

大厂面试冲刺,Java“实战”问题三连,你碰到了哪个?

推荐学习...

亿级分库分表,如何丝滑扩容、如何双写灰度

以下是基于亿级分库分表丝滑扩容与双写灰度设计方案,结合架构图与核心流程说明:一、总体设计目标...

MYSQL表设计规范(mysql表设计原则)

日常工作总结,不是通用规范一、表设计库名、表名、字段名必须使用小写字母,“_”分割。...

怎么解决MySQL中的Duplicate entry错误?

在使用MySQL数据库时,我们经常会遇到Duplicateentry错误,这是由于插入或更新数据时出现了重复的唯一键值。这种错误可能会导致数据的不一致性和完整性问题。为了解决这个问题,我们可以采取以...

高并发下如何防重?(高并发如何防止重复)

前言最近测试给我提了一个bug,说我之前提供的一个批量复制商品的接口,产生了重复的商品数据。...

性能压测数据告诉你MySQL和MariaDB该怎么选

1.压测环境为了尽可能的客观公正,本次选择同一物理机上的两台虚拟机,一台用作数据库服务器,一台用作运行压测工具mysqlslap,操作系统均为UbuntuServer22.04LTS。...

屠龙之技 --sql注入 不值得浪费超过十天 实战中sqlmap--lv 3通杀全国

MySQL小结发表于2020-09-21分类于知识整理阅读次数:本文字数:67k阅读时长≈1:01...

破防了,谁懂啊家人们:记一次 mysql 问题排查

作者:温粥一、前言谁懂啊家人们,作为一名java开发,原来以为mysql这东西,写写CRUD,不是有手就行吗;你说DDL啊,不就是设计个表结构,搞几个索引吗。...

SpringBoot系列Mybatis之批量插入的几种姿势

...

MySQL 之 Performance Schema(mysql安装及配置超详细教程)

MySQL之PerformanceSchema介绍PerformanceSchema提供了在数据库运行时实时检查MySQL服务器的内部执行情况的方法,通过监视MySQL服务器的事件来实现监视内...

取消回复欢迎 发表评论: