当前位置: 首页 > news >正文

Python核心库Pandas详解:数据处理与分析利器

文章目录

  • 前言
  • 一、Pandas核心数据结构:Series与DataFrame
    • 1.1 Series:带标签的一维数组
    • 1.2 DataFrame:二维表格型数据结构
    • 1.3 Series与DataFrame的关系
    • 1.4 数据结构选择指南
  • 二、核心语法
    • 2.1 数据输入/输出:支持多种格式
    • 2.2 数据选择与索引
    • 2.3 数据清洗与预处理
    • 2.4 数据分组与聚合
    • 2.5 表格合并:concat, merge, join
      • pd.concat:沿轴堆叠数据
      • pd.merge:基于键值连接(类似SQL JOIN)
      • df.join:基于索引的连接
      • 三种方法对比与选择指南
      • 注意事项
    • 2.6 时间序列处理
      • 时间序列基础
      • 时间序列索引操作
      • 时间重采样(Resampling)
      • 滑动窗口操作
      • 时间偏移与日期范围
      • 时区处理
  • 总结与学习资源


前言

在这里插入图片描述

Pandas是Python数据分析领域最核心的库之一,构建于NumPy之上,提供了高效便捷的数据结构和数据分析工具。本文将深入解析Pandas的核心概念与功能。


一、Pandas核心数据结构:Series与DataFrame

Pandas的强大源于其两个核心数据结构:Series(一维数据)DataFrame(二维表格)。它们为数据处理提供了高效且直观的容器,支持自动数据对齐、灵活索引和丰富的操作方法。

1.1 Series:带标签的一维数组

  1. 核心特性
    • 带索引的数组:每个元素都有对应的标签。
    • 数据类型统一:所有元素共享同一数据类型(int, float, string等)。
    • 大小不可变:创建后不能改变大小(但内容可修改)。
  2. 创建Series
import pandas as pd
import numpy as np# 从列表创建
s1 = pd.Series([10, 20, 30, 40])# 从数组创建(带自定义索引)
s2 = pd.Series(np.array([1.1, 2.2, 3.3]), index=['a', 'b', 'c'],name="温度数据",dtype='float32')# 从字典创建(键自动转为索引)
s3 = pd.Series({'北京': 2154, '上海': 2428, '广州': 1490})
  1. 关键属性
print(s2.index)    # Index(['a', 'b', 'c'], dtype='object')
print(s2.values)   # array([1.1, 2.2, 3.3], dtype=float32)
print(s2.dtype)    # float32
print(s2.name)     # '温度数据'
print(s2.shape)    # (3,)
  1. 索引与切片
# 位置索引
print(s2[0])       # 1.1# 标签索引
print(s2['b'])     # 2.2# 切片操作
print(s2[1:])      # b:2.2, c:3.3
print(s2['a':'c']) # 包含两端点(与Python切片不同)# 布尔索引
print(s2[s2 > 2])  # b:2.2, c:3.3
  1. 重要功能
# 向量化运算
print(s2 * 10)     # a:11.0, b:22.0, c:33.0# 索引对齐运算
s4 = pd.Series([10, 20], index=['a', 'd'])
print(s2 + s4)     # a:11.1, b:NaN, c:NaN, d:NaN# 缺失值处理
print((s2 + s4).fillna(0))  # a:11.1, b:0, c:0, d:0# 统计方法
print(s2.mean())   # 2.2
print(s2.idxmax()) # 'c' (最大值索引)

1.2 DataFrame:二维表格型数据结构

  1. 核心特性
    • 行索引(index) + 列标签(columns) 的二维结构
    • 每列是一个Series(可不同数据类型)
    • 大小可变(可动态增删行列)
  2. 创建DataFrame
# 从字典创建(最常用)
data = {'城市': ['北京', '上海', '广州', '深圳'],'人口(万)': [2154, 2428, 1490, 1303],'GDP(万亿)': [3.92, 4.32, 2.82, 2.76]
}
df = pd.DataFrame(data, index=['a', 'b', 'c', 'd'])data = {'Name': ['Alice', 'Bob', 'Charlie'],'Age': [25, 30, 35],'City': ['NY', 'LA', 'SF']
}
df = pd.DataFrame(data)
print(df)# 从列表创建
data = [['北京', 2154], ['上海', 2428], ['广州', 1490]]
df2 = pd.DataFrame(data, columns=['城市', '人口'])# 从NumPy数组创建
arr = np.random.rand(4, 3)
df3 = pd.DataFrame(arr, columns=['A', 'B', 'C'])
  1. 关键属性
print(df.index)     # Index(['a', 'b', 'c', 'd'], dtype='object')
print(df.columns)   # Index(['城市', '人口(万)', 'GDP(万亿)'], dtype='object')
print(df.dtypes)    # 城市:object, 人口(万):int64, GDP(万亿):float64
print(df.shape)     # (4, 3)
print(df.values)    # 底层NumPy数组
  1. 数据访问
# 选择列(返回Series)
pop_series = df['人口(万)'] # 选择多列
sub_df = df[['城市', 'GDP(万亿)']]# 行选择(loc基于标签)
print(df.loc['b'])              # 第二行数据
print(df.loc[['a', 'c']])       # 多行数据# 行选择(iloc基于位置)
print(df.iloc[0])               # 第一行
print(df.iloc[1:3])             # 第二、三行# 行列混合选择
print(df.loc['c', 'GDP(万亿)']) # 2.82
print(df.iloc[2, 1])            # 1490
  1. 数据操作
# 新增列
df['人均GDP'] = df['GDP(万亿)'] * 10000 / df['人口(万)']# 删除列
df.drop('人均GDP', axis=1, inplace=True)# 修改值
df.loc['a', '人口(万)'] = 2200# 条件筛选
high_gdp = df[df['GDP(万亿)'] > 3]  # GDP>3万亿的城市# 排序
df.sort_values('人口(万)', ascending=False)
  1. 高级索引
# 多层索引(MultiIndex)
index = pd.MultiIndex.from_tuples([('华东', '上海'), ('华东', '杭州'),('华南', '广州'),('华南', '深圳')
])
df_multi = pd.DataFrame(np.random.randn(4, 2), index=index,columns=['指标1', '指标2'])# 多层索引访问
print(df_multi.loc[('华南', '广州')])
print(df_multi.xs('华东', level=0))  # 华东地区所有城市

1.3 Series与DataFrame的关系

  1. 结构关系:
    • DataFrame可视为由多个Series组成的字典(列名为键)
    • DataFrame的每一列都是Series对象
  2. 相互转换:
# Series转DataFrame
s = pd.Series([1, 2, 3], name='值')
s_df = s.to_frame()# DataFrame单列转Series
df_col = df['人口(万)'].squeeze()  # 转为Series
  1. 运算兼容性:
# DataFrame与Series运算(自动按列广播)
df['人口(万)'] = df['人口(万)'] * 1.05  # 所有城市人口增长5%

1.4 数据结构选择指南

场景推荐结构
单列数据(温度序列Series
多列关联数据(城市统计表)DataFrame
时间序列数据Series(带DatetimeIndex)
面板数据(三维数据)使用MultiIndex的DataFrame

掌握Series和DataFrame是高效使用Pandas的基础。它们的设计充分考虑了数据操作的便捷性和性能,通过索引对齐、向量化运算等特性,让复杂的数据处理变得简单直观。

二、核心语法

2.1 数据输入/输出:支持多种格式

# 读写文件示例
df.to_csv('data.csv', index=False)  # 写入CSV
df_excel = pd.read_excel('data.xlsx')  # 读取Excel
df_sql = pd.read_sql('SELECT * FROM table', con)  # 从SQL读取

支持格式:

  • CSV、Excel
  • JSON、HTML
  • SQL数据库
  • Parquet、HDF5(大数据存储)

2.2 数据选择与索引

  1. 基于标签选择:loc
print(df.loc[0, 'Name'])  # 输出: Alice
print(df.loc[:, ['Name', 'City']])  # 选择多列
  1. 基于位置选择:iloc
print(df.iloc[1, 2])  # 输出: LA (第二行第三列)
  1. 布尔索引
print(df[df['Age'] > 28])  # 筛选年龄>28的行

2.3 数据清洗与预处理

  1. 处理缺失值
df.fillna(0)  # 填充为0
df.dropna()   # 删除含NaN的行
  1. 重复值处理
df.drop_duplicates()  # 删除重复行
  1. 数据转换
df['Age'].apply(lambda x: x+1)  # 年龄列+1
df.replace('NY', 'New York')    # 值替换

2.4 数据分组与聚合

# 按城市分组计算平均年龄
grouped = df.groupby('City')['Age'].mean()
print(grouped)
City
LA    30
NY    25
SF    35
Name: Age, dtype: int64

2.5 表格合并:concat, merge, join

在数据处理中,表格合并是最常见的操作之一。Pandas提供了三种主要的合并方法:concat、merge和join。它们各有特点,适用于不同的合并场景。

pd.concat:沿轴堆叠数据

concat主要用于沿指定轴(行或列)堆叠多个DataFrame或Series,是最简单的数据拼接方法。
基本语法:

pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None)

核心参数:

参数说明
objs要连接的DataFrame/Series列表
axis连接轴:0=行方向(纵向),1=列方向(横向)
join连接方式:‘outer’(并集,默认)或 ‘inner’(交集)
ignore_index是否重置索引(默认False保留原索引)
keys创建多层索引,标识原始数据来源

示意图:

DataFrame A (3x2)        DataFrame B (2x2)X   Y                    X   Y
0  A0  B0               0  C0  D0
1  A1  B1               1  C1  D1
2  A2  B2沿行轴堆叠 (axis=0):X   Y
0  A0  B0
1  A1  B1
2  A2  B2
0  C0  D0  ← 保留原始索引
1  C1  D1沿列轴堆叠 (axis=1):X   Y   X   Y
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  NaN NaN  ← 缺失值填充

使用示例:
纵向堆叠(增加行):

df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})# 纵向堆叠
result = pd.concat([df1, df2])
    A   B
0  A0  B0
1  A1  B1
0  A2  B2
1  A3  B3

横向拼接(增加列):

df3 = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']})# 横向拼接
result = pd.concat([df1, df3], axis=1)
    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1

处理索引和列名:

# 重置索引
result = pd.concat([df1, df2], ignore_index=True)# 添加来源标识
result = pd.concat([df1, df2], keys=['df1', 'df2'])
        A   B
df1 0  A0  B01  A1  B1
df2 0  A2  B21  A3  B3

内连接(只保留共有列):

df4 = pd.DataFrame({'A': ['A2', 'A3'], 'C': ['C2', 'C3']})# 内连接(只保留A列)
result = pd.concat([df1, df4], join='inner')

pd.merge:基于键值连接(类似SQL JOIN)

merge用于基于一个或多个键(列)将不同DataFrame的行连接起来,功能最强大,类似SQL的JOIN操作。
基本语法:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None)

核心参数:

参数说明
left/right要连接的左右DataFrame
how连接类型:‘inner’, ‘outer’, ‘left’, ‘right’
on连接键(两表共有列名)
left_on/right_on左右表不同的连接键
suffixes列名冲突时的后缀(默认(‘_x’, ‘_y’))

连接类型(how参数):

连接类型说明SQL等效
inner内连接(默认)INNER JOIN
outer全外连接FULL OUTER JOIN
left左连接LEFT JOIN
right右连接RIGHT JOIN

示意图:

Left DataFrame (df1)       Right DataFrame (df2)Key   ValL                Key   ValR
0  K0    A0               0  K0    B0
1  K1    A1               1  K2    B1
2  K2    A2               2  K3    B2内连接 (how='inner', on='Key'):Key   ValL  ValR
0  K0    A0    B0    ← 仅保留两表共有的键 (K0, K2)
1  K2    A2    B1左连接 (how='left', on='Key'):Key   ValL  ValR
0  K0    A0    B0
1  K1    A1    NaN   ← 保留左表所有键
2  K2    A2    B1

使用示例:
多键连接:

left_multi = pd.DataFrame({'key1': ['K0', 'K0'], 'key2': ['K0', 'K1'], 'A': ['A0', 'A1']})
right_multi = pd.DataFrame({'key1': ['K0', 'K0'], 'key2': ['K0', 'K0'], 'B': ['B0', 'B1']})result = pd.merge(left_multi, right_multi, on=['key1', 'key2'])
  key1 key2   A   B
0   K0   K0  A0  B0

df.join:基于索引的连接

join是merge的简化版,主要用于基于索引的连接,语法更简洁。
基本语法:

df1.join(df2, how='left', lsuffix='', rsuffix='')

核心特点:

  • 默认基于索引连接(除非通过on指定列)
  • 默认左连接(how=‘left’)
  • 可同时连接多个DataFrame
  • 处理列名冲突时添加后缀

示意图:

Left DataFrame (df1)       Right DataFrame (df2)ValL                      ValR
K0  A0                    K0  B0
K1  A1                    K2  B1
K2  A2左连接 (how='left'):ValL  ValRK0  A0    B0K1  A1    NaN   ← 保留左表所有索引K2  A2    B1外连接 (how='outer'):ValL  ValRK0  A0    B0K1  A1    NaNK2  A2    B1K3  NaN   B2   ← 保留两表所有索引

使用示例:
基本索引连接:

left = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']}, index=['K0', 'K1'])
right = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']}, index=['K0', 'K2'])# 左连接(默认)
result = left.join(right)
     A   B    C    D
K0  A0  B0   C0   D0
K1  A1  B1  NaN  NaN

连接多个DataFrame:

right2 = pd.DataFrame({'E': ['E0', 'E1']}, index=['K0', 'K1'])
result = left.join([right, right2])

基于列连接(转为索引):

# 将列设为索引后再连接
result = left.set_index('key').join(right.set_index('key'))

三种方法对比与选择指南

特性concatmergejoin
主要用途简单堆叠键值连接索引连接
连接维度行或列索引
连接逻辑位置对齐键值匹配索引匹配
多表连接支持仅两表支持多表
列名处理自动处理后缀处理后缀处理
索引保留可选保留新建索引保留左索引

选择指南:

  • 需要简单堆叠数据 → concat
  • 需要基于列值连接(类似SQL JOIN) → merge
  • 需要基于索引连接 → join
  • 连接多个表 → concat(轴向堆叠)或 join(索引连接)
  • 需要复杂连接条件 → merge

注意事项

  1. 处理大型数据集
# 分块合并大文件
chunk_iter = pd.read_csv('large.csv', chunksize=10000)
results = []
for chunk in chunk_iter:merged = pd.merge(chunk, lookup_table, on='id')results.append(merged)final = pd.concat(results)
  1. 性能优化
# 设置索引加速连接
left.set_index('key', inplace=True)
right.set_index('key', inplace=True)
result = left.join(right)  # 比merge更快
  1. 避免常见错误
# 错误:列名相同导致冲突
result = pd.merge(left, right, on='key')  # 非连接列同名会加后缀# 正确:显式指定后缀
result = pd.merge(left, right, on='key', suffixes=('_left', '_right'))
  1. 复杂条件合并
# 非等值合并(merge不支持,需筛选后concat)
cond = (left['date'] >= right['start_date']) & (left['date'] <= right['end_date'])
filtered = left[cond].reset_index(drop=True)
result = pd.merge(filtered, right, left_index=True, right_index=True)
  1. 多层索引合并
# 多层索引连接
left_index = pd.MultiIndex.from_tuples([('A',1), ('B',2)])
right_index = pd.MultiIndex.from_tuples([('A',1), ('C',3)])result = left.set_index(left_index).join(right.set_index(right_index))

掌握concat、merge和join的使用场景和技巧,能够高效地解决各类数据合并问题,是Pandas数据处理的核心技能之一。根据数据特性和需求选择合适的方法,可以大幅提升数据整合的效率和质量。

2.6 时间序列处理

Pandas提供了强大的时间序列处理功能,尤其适用于金融、物联网、日志分析等领域。其核心是TimestampDatetimeIndexPeriod对象,结合重采样、滑动窗口等操作,可以高效处理时间相关数据。
时间序列索引结构原理

时间序列基础

  1. 时间戳创建
import pandas as pd
import numpy as np# 单个时间戳
ts = pd.Timestamp('2023-08-15 14:30:00')
print(ts.year, ts.month, ts.day)  # 2023 8 15# 时间序列
dates = pd.date_range('2023-01-01', periods=5, freq='D')
print(dates)
DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'],dtype='datetime64[ns]', freq='D')
  1. 时间频率代码
代码说明代码说明
D日历日B工作日
H小时T或min分钟
SL或ms毫秒
M月末Q季末
A年末W
BM工作日月末QS季初

时间序列索引操作

  1. 创建时间索引序列
# 创建带时间索引的Series
ts = pd.Series(np.random.randn(5), index=dates)
print(ts)
2023-01-01    0.469
2023-01-02   -0.282
2023-01-03   -1.509
2023-01-04   -1.136
2023-01-05    1.212
Freq: D, dtype: float64
  1. 时间切片与选择
# 按年份切片
print(ts['2023'])# 按月份切片
print(ts['2023-01'])# 按日期范围
print(ts['2023-01-02':'2023-01-04'])# 部分字符串匹配
print(ts.truncate(before='2023-01-03'))
  1. 时间属性访问
# 提取日期组件
print(ts.index.year)
print(ts.index.day_name())# 添加为数据列
ts['Year'] = ts.index.year
ts['Quarter'] = ts.index.quarter

时间重采样(Resampling)

重采样是时间序列处理的核心操作,用于改变时间频率。

  1. 降采样(低频聚合)
# 日数据 -> 月均值
monthly = ts.resample('M').mean()
print(monthly)
2023-01-31   -0.449
Freq: M, dtype: float64
  1. 升采样(高频插值)
# 日数据 -> 小时数据(前向填充)
hourly = ts.resample('6H').ffill()
print(hourly.head())
2023-01-01 00:00:00    0.469
2023-01-01 06:00:00    0.469
2023-01-01 12:00:00    0.469
2023-01-01 18:00:00    0.469
2023-01-02 00:00:00   -0.282
Freq: 6H, dtype: float64
  1. 灵活的重采样方法
# 自定义聚合
result = ts.resample('W').agg(['min', 'max', 'mean'])# OHLC金融数据(开盘、最高、最低、收盘)
ohlc = ts.resample('D').ohlc()# 分组重采样
grouped = df.groupby('Category').resample('W').sum()

滑动窗口操作

  1. 滚动窗口(Rolling)
# 3天滚动平均
rolling_mean = ts.rolling(window=3).mean()
print(rolling_mean)
2023-01-01         NaN
2023-01-02         NaN
2023-01-03   -0.440667
2023-01-04   -0.975667
2023-01-05   -0.144333
dtype: float64
  1. 扩展窗口(Expanding)
# 累计平均
expanding_mean = ts.expanding().mean()
  1. 指数加权窗口(EWM)
# 指数加权移动平均
ewma = ts.ewm(span=7).mean()
  1. 自定义窗口计算
# 滚动窗口应用自定义函数
def custom_agg(window):return window.max() - window.min()ts.rolling(5).apply(custom_agg)

时间偏移与日期范围

  1. 时间偏移(DateOffset)
# 基础偏移
print(ts.index + pd.DateOffset(days=3))# 工作日偏移
from pandas.tseries.offsets import BDay
print(ts.index + 2*BDay())# 复杂偏移
offset = pd.DateOffset(months=2, days=10)
print(ts.index + offset)
  1. 日期范围生成
# 工作日范围
bdate_range = pd.bdate_range('2023-01-01', periods=5)# 自定义频率
custom_range = pd.date_range('2023-01-01', periods=12, freq='2W-TUE')
  1. 节假日处理
from pandas.tseries.holiday import USFederalHolidayCalendar# 创建美国节假日日历
cal = USFederalHolidayCalendar()
holidays = cal.holidays('2023-01-01', '2023-12-31')# 工作日计算(排除节假日)
bday_us = pd.offsets.CustomBusinessDay(calendar=cal)

时区处理

# 设置时区
ts_utc = ts.tz_localize('UTC')
print(ts_utc.index)
DatetimeIndex(['2023-01-01 00:00:00+00:00', ...],dtype='datetime64[ns, UTC]', freq='D')

通过灵活组合时间索引、重采样和窗口操作,可以提取出丰富的时间特征,为后续分析和建模打下坚实基础。


总结与学习资源

Pandas的核心价值在于:

  • 提供表格化数据结构,直观易用
  • 实现高效数据清洗复杂分析

学习资源:

  • 官方文档
  • 《Python for Data Analysis》(作者:Pandas创始人Wes McKinney)
  • Kaggle Pandas教程

掌握Pandas将极大提升你的数据处理能力,为数据科学和机器学习打下坚实基础!

相关文章:

  • 网站建设服务商城湘潭seo快速排名
  • ios网站开发教程产品推广的目的和意义
  • 为拟建设的网站申请一个域名国内做网站比较好的公司
  • 平台网站建设网站百度一下官网页
  • mip手机网站模板网站源码平台
  • 可以和朋友合资做网站吗seo优化网站优化
  • 【最新实时目标检测YOLOv13添加PyQt可视化界面】
  • 旁挂式集中转发AC基础配置
  • 对手机屏中断路和短路的单元进行切割或熔接,实现液晶线路激光修复原理
  • 《贵州棒垒球》有什么国家级比赛·棒球1号位
  • Qt面试题汇总
  • 集成 Odoo、n8n 与 Dify,实现智能业务流程自动化
  • 通过环境变量管理多版本JDK8、11、17并安装idea编译器
  • 第十节 新特性与趋势-CSS层叠规则升级
  • WPF 几种绑定 (笔记)
  • Docker 安装与配置 详解——AI教你学Docker
  • 实物建模性能优化秘籍:如何将模型面数减少且保持质感
  • 实现OFD转换PDF文件的实用方法
  • 计算机基础和Java编程的练习题
  • (LeetCode 每日一题) 2200. 找出数组中的所有 K 近邻下标 (双指针)
  • CasaOS中Docker部署SyncThing结合Cpolar实现公网文件同步方案
  • Kafka 监控与调优实战指南(二)
  • 华为云Flexus+DeepSeek征文 | 华为云MaaS平台上的智能客服Agent开发:多渠道融合应用案例
  • 《高并发系统的一致性保障:RocketMQ事务消息实现原理与应用》
  • JAVA的springboot项目使用AliMQ示例
  • vftp centos 离线部署