Pandas 入门实战:30 分钟掌握数据分析核心操作

作者:狼烟四起2026.11.07 01:55浏览量:0

简介:本文面向 Python 数据分析初学者,旨在通过 30 分钟的系统学习,帮助读者快速掌握 Pandas 库中最核心、最高频的数据操作技能。文章从数据导入导出、数据查看、数据选择与过滤、数据清洗、数据重塑、分组聚合、数据合并、时间序列处理到综合实战,层层递进,结合大量可直接运行的代码示例,构建完整的数据分析知识框架。读完本文,您将能够独立完成从数据加载到结果输出的全流程操作,为后续进阶学习打下坚实基础。

引言

在数据驱动的时代,高效处理和分析数据已成为开发者与数据工作者的必备技能。Pandas 作为 Python 生态中用于数据分析和清洗的核心库,凭借其强大的 Series 与 DataFrame 数据结构,以及对表格数据的灵活操作能力,成为数据科学领域的事实标准。无论是数据挖掘、机器学习预处理,还是商业智能报表,Pandas 都扮演着至关重要的角色。

然而,Pandas 功能庞大,初学者往往面对海量 API 感到无从下手。本文提炼出实际项目中最常用的操作场景,以 30 分钟为限,构建从数据导入到结果导出的完整闭环,帮助读者建立清晰的操作脉络。

一、数据导入与导出:建立数据通道

数据分析的第一步是获取数据。Pandas 支持多种数据源格式,以下展示最常见的几种导入方式。

从文件与数据库导入

  1. import pandas as pd
  2. import numpy as np
  3. # 从 CSV 文件读取数据
  4. df_csv = pd.read_csv('data.csv')
  5. # 从 Excel 文件读取指定工作表
  6. df_excel = pd.read_excel('data.xlsx', sheet_name='Sheet1')
  7. # 从 SQL 数据库读取(以 SQLite 为例)
  8. from sqlalchemy import create_engine
  9. engine = create_engine('sqlite:///mydatabase.db')
  10. df_sql = pd.read_sql('SELECT * FROM orders', engine)
  11. # 从字典创建 DataFrame
  12. data = {'姓名': ['张三', '李四'], '年龄': [28, 32], '城市': ['北京', '上海']}
  13. df_dict = pd.DataFrame(data)

数据导出至目标格式

  1. # 导出为 CSV,index=False 去除索引列,utf-8-sig 保证 Excel 中文兼容
  2. df.to_csv('output.csv', index=False, encoding='utf-8-sig')
  3. # 导出到 Excel 文件
  4. df.to_excel('output.xlsx', sheet_name='report', index=False)
  5. # 导出到 SQL 数据库,if_exists='replace' 表示覆盖原表
  6. df.to_sql('table_name', engine, if_exists='replace', index=False)

要点提示:在读取大文件时,可指定 nrows 参数预览前 N 行,或使用 chunksize 分块读取,以缓解内存压力。导出时注意编码与索引处理,避免数据错位。

二、数据查看与基本信息:快速洞察数据全貌

拿到数据后,首要任务是了解数据结构、类型与质量状况。Pandas 提供了简洁的探测方法。

数据概览与结构信息

  1. # 生成示例数据
  2. data = {
  3. '姓名': ['张三', '李四', '王五', '赵六', '钱七'],
  4. '年龄': [25, 30, None, 40, 45],
  5. '城市': ['北京', '上海', '广州', '深圳', '杭州'],
  6. '工资': [10000, 15000, 12000, 20000, 25000],
  7. '入职日期': ['2020-01-15', '2019-05-20', '2021-03-10', '2018-07-05', '2022-02-28']
  8. }
  9. df = pd.DataFrame(data)
  10. df['入职日期'] = pd.to_datetime(df['入职日期'])
  11. # 查看前 3 行与后 2 行
  12. print(df.head(3))
  13. print(df.tail(2))
  14. # 查看整体结构信息:索引范围、列名、非空值数量、数据类型、内存占用
  15. df.info()
  16. # 数值列统计摘要:均值、标准差、分位数、极值
  17. df.describe()
  18. # 查看形状(行数、列数)
  19. print(df.shape) # 输出 (5, 5)
  20. # 查看列名与索引对象
  21. print(df.columns)
  22. print(df.index)
  23. # 检查每列缺失值数量
  24. print(df.isnull().sum())

扩展解读:df.info() 在数据清洗前非常有价值,可以直观看到每一列的数据类型与缺失情况,辅助决定后续处理策略。describe() 默认只统计数值列,如需包含分类列,可设置 include='all'。

三、数据选择与过滤:精准定位目标数据

数据选择是 DataFrame 操作中最频繁的动作,需熟练掌握位置索引、标签索引与条件过滤。

列选择与行过滤

  1. # 选择单列,返回 Series
  2. s_name = df['姓名']
  3. # 选择多列,返回 DataFrame
  4. df_subset = df[['姓名', '年龄']]
  5. # 使用点号操作符(列名需为合法标识符)
  6. s_age = df.年龄
  7. # 通过布尔条件过滤行
  8. df_high_salary = df[df['工资'] > 15000]
  9. # 多条件组合:& 表示与,| 表示或,~ 表示非
  10. df_condition = df[(df['年龄'] < 40) & (df['城市'].isin(['北京', '上海'])]
  11. # 使用 loc 与 iloc 进行标签/位置切片
  12. df.loc[1:3, ['姓名', '工资']] # 行标签 1 到 3,闭区间
  13. df.iloc[0:2, 0:2] # 前两行前两列,开区间
  14. # 按条件筛选指定列
  15. df.filter(items=['姓名', '年龄'], axis=1)

细节提示:布尔索引是 Pandas 最强大特性之一。注意逻辑运算符必须使用 &、|,且每个条件需加括号。loc 切片包含末端标签,而 iloc 则遵循 Python 左闭右开原则,两者极易混淆,应重点区分。

四、数据清洗与处理:保证数据质量

真实数据往往包含缺失值、重复值、异常值。清洗环节决定后续分析的可靠性。

缺失值处理策略

  1. # 检测缺失值
  2. df.isnull() # 逐元素布尔表
  3. df.isnull().sum() # 每列缺失总数
  4. # 删除含缺失值的行(axis=0)或列(axis=1)
  5. df_dropna = df.dropna(axis=0, how='any') # how='all' 仅删除全为缺失值的行
  6. # 填充缺失值:常数、前向填充、后向填充、均值/中位数
  7. df_fill = df.fillna(value={'年龄': df['年龄'].mean()}) # 用均值填充
  8. df_fill_ffill = df.fillna(method='ffill') # 用上一行值填充
  9. # 插值法填充
  10. df_interpolate = df.interpolate() # 线性插值,适合时间序列

重复值与异常值处理

  1. # 检测重复行
  2. duplicated_mask = df.duplicated(subset=['姓名'], keep='first')
  3. df_unique = df.drop_duplicates(subset=['姓名'], keep='first')
  4. # 异常值识别(以年龄为例,基于标准差)
  5. mean_age = df['年龄'].mean()
  6. std_age = df['年龄'].std()
  7. df_outlier = df[(df['年龄'] > mean_age - 3 * std_age) & (df['年龄'] < mean_age + 3 * std_age)]

数据类型转换

  1. # 强制类型转换
  2. df['年龄'] = df['年龄'].astype('float64')
  3. # 自定义转换函数
  4. df['工资'] = df['工资'].apply(lambda x: x / 10000) # 转换为万元

实用建议:清洗策略需结合业务场景。若缺失比例低于 5%,可考虑直接删除;若为关键字段,优先采用中位数或众数填充。处理时间序列数据时,前向/后向填充往往比均值填充更合理。

五、数据转换与重塑:灵活的表格变形

数据透视与行列转换在报表聚合中极为常见,Pandas 提供了 melt、pivot 等方法实现结构变换。

宽表与长表的互相转换

  1. # 从宽表转为长表(melt)
  2. df_melted = pd.melt(df, id_vars=['姓名'], value_vars=['工资', '年龄'],
  3. var_name='指标', value_name='数值')
  4. # 从长表转为宽表(pivot)
  5. df_pivot = df_melted.pivot(index='姓名', columns='指标', values='数值')
  6. # stack / unstack:作用于多层索引
  7. df_stack = df.set_index(['姓名', '城市']).stack()
  8. df_unstack = df_stack.unstack(level=0)

排序与排名

  1. # 按单列/多列排序
  2. df_sorted = df.sort_values(by=['年龄', '工资'], ascending=[True, False])
  3. # 添加排名
  4. df['工资排名'] = df['工资'].rank(method='dense', ascending=False)

场景举例:当多个特征以列存在而分析需要以行排列时,melt 可快速将宽表展开;pivot 能实现类似 Excel 透视表的功能,对分组数据重建交叉表。

六、数据聚合与分组:发现数据背后的规律

分组聚合是数据分析中价值密度最高的操作。groupby 配合多种聚合函数可实现高效统计。

单列与多列分组

  1. # 按城市分组,计算工资均值
  2. group_mean = df.groupby('城市')['工资'].mean()
  3. # 按多列分组,多个聚合函数
  4. group_agg = df.groupby(['城市', '入职日期']).agg({
  5. '工资': ['sum', 'mean', 'count'],
  6. '年龄': 'median'
  7. })
  8. # 使用 named aggregation
  9. group_named = df.groupby('城市').agg(
  10. 平均工资=('工资', 'mean'),
  11. 最高工资=('工资', 'max'),
  12. 人数=('姓名', 'count')
  13. )
  14. # 分组后遍历,适用于复杂逻辑
  15. for city, group in df.groupby('城市'):
  16. print(f"城市: {city}, 平均年龄: {group['年龄'].mean()}")

使用 apply 进行自定义聚合

  1. # 自定义函数:计算极差
  2. def range_func(series):
  3. return series.max() - series.min()
  4. df_apply = df.groupby('城市')['工资'].apply(range_func)

进阶技巧:groupby 后可以配合 transform 保留原始行数,如计算每位员工工资与城市均值的差值。filter 方法可根据分组统计结果过滤原始行,如保留人数大于 2 的城市。

七、数据合并与连接:整合多源数据

在真实项目中,数据往往分散于多个表或文件,合并操作是数据整合的基础。

纵向合并与横向拼接

  1. # 创建两组数据
  2. df1 = pd.DataFrame({'ID': [1, 2, 3], '工资': [10000, 15000, 12000]})
  3. df2 = pd.DataFrame({'ID': [4, 5], '工资': [20000, 25000]})
  4. df3 = pd.DataFrame({'ID': [1, 2], '绩效': ['A', 'B']})
  5. # 纵向拼接(行合并)
  6. df_concat = pd.concat([df1, df2], axis=0, ignore_index=True)
  7. # 横向拼接(列合并)
  8. df_concat_col = pd.concat([df1.set_index('ID'), df3.set_index('ID')], axis=1, join='inner')

类 SQL 连接操作

  1. # 内连接:仅保留匹配的行
  2. df_inner = pd.merge(df1, df3, on='ID', how='inner')
  3. # 左连接:保留左表所有行
  4. df_left = pd.merge(df1, df3, on='ID', how='left')
  5. # 右连接与全外连接
  6. df_right = pd.merge(df1, df3, on='ID', how='right')
  7. df_outer = pd.merge(df1, df3, on='ID', how='outer')
  8. # 当键列名称不同时,指定 left_on 与 right_on
  9. df_custom = pd.merge(df1, df3, left_on='ID', right_on='ID', how='left')

注意事项:合并前务必确认关联键的唯一性(或明确可容忍的笛卡尔积)。merge 默认做内连接,且会对重名列自动追加后缀,可通过 suffixes 参数自定义。

八、时间序列处理:掌握时间维度分析

时间序列是金融、物联网、运营分析中最常见的数据类型。Pandas 提供了丰富的时间处理工具。

时间索引与重采样

  1. # 将字符串列转为时间类型,并设置为索引
  2. df_time = df.copy()
  3. df_time['入职日期'] = pd.to_datetime(df_time['入职日期'])
  4. df_time.set_index('入职日期', inplace=True)
  5. # 按月份重采样,计算月度平均工资
  6. df_monthly = df_time.resample('M')['工资'].mean()
  7. # 按季度聚合
  8. df_quarterly = df_time.resample('Q')['工资'].agg(['sum', 'count', 'mean'])
  9. # 时间差计算
  10. df_time['工龄天数'] = (pd.Timestamp.now() - df_time.index).days

平移与差分

  1. # 计算环比变化(本月与上月差额)
  2. df_time['工资环比'] = df_time['工资'].diff(periods=1)
  3. # 计算增长率
  4. df_time['工资增长率'] = df_time['工资'].pct_change() * 100
  5. # 移动平均平滑
  6. df_time['移动平均3月'] = df_time['工资'].rolling(window=3).mean()

实战要点:重采样前必须保证索引为 DatetimeIndex。resample 支持频率参数 ‘M’ 月度末、’MS’ 月度初、’Q’ 季度末、’H’ 小时等。滚动窗口的 min_periods 参数可控制窗口内最少有效值数,避免前几行产生 NaN。

九、实用案例:10 分钟完成分析流水线

将上述所有知识点串联,构建一个完整的实战示例,题目为:员工工资分析报告。

  1. import pandas as pd
  2. import numpy as np
  3. # 1. 数据读取
  4. df = pd.read_csv('employees.csv', encoding='utf-8-sig')
  5. # 2. 数据审阅
  6. print("数据形状:", df.shape)
  7. print("缺失值统计:\n", df.isnull().sum())
  8. # 3. 数据清洗
  9. df = df.drop_duplicates(subset='员工ID')
  10. df['年龄'].fillna(df['年龄'].median(), inplace=True)
  11. df['入职日期'] = pd.to_datetime(df['入职日期'])
  12. # 4. 特征衍生
  13. df['入职年份'] = df['入职日期'].dt.year
  14. df['工龄'] = (pd.Timestamp.now() - df['入职日期']).dt.days // 365
  15. # 5. 分组聚合分析
  16. # 各部门平均工资与人数
  17. dept_stats = df.groupby('部门').agg(
  18. 平均工资=('工资', 'mean'),
  19. 人数=('员工ID', 'count'),
  20. 平均工龄=('工龄', 'mean')
  21. ).reset_index()
  22. # 高薪员工筛选(工资高于部门平均水平 1.2 倍)
  23. df['部门平均工资'] = df.groupby('部门')['工资'].transform('mean')
  24. df['高薪标记'] = np.where(df['工资'] > 1.2 * df['部门平均工资'], '是', '否')
  25. # 6. 结果导出
  26. dept_stats.to_excel('部门薪资统计.xlsx', index=False)
  27. df[df['高薪标记'] == '是'].to_csv('高薪员工名单.csv', index=False, encoding='utf-8-sig')
  28. print("分析完成,结果已输出。")

该案例涵盖了数据导入、探索、清洗、聚合、条件标记与导出的一整套流程,是日常分析工作的标准范式。

十、总结与进阶建议

本文系统梳理了 Pandas 入门所需的六大核心能力:数据读写、数据探查、数据筛选、数据清洗、数据聚合与数据合并,并辅以时间序列处理和完整实战。30 分钟的学习虽然只能覆盖高频操作,但已经足以构建起独立解决数据问题的能力框架。

后续学习方向建议

  1. 深入理解索引机制:掌握 MultiIndex、set_index / reset_index 的精髓,对复杂数据结构操作至关重要。
  2. 性能优化:学习向量化操作,避免循环;掌握 numba 加速与 eval/query 方法。
  3. 可视化联动:配合绘图库进行数据分析的可视化呈现,使分析结果更具说服力。
  4. 大数据扩展:当单机内存不足时,学习分块处理、Dask 等分布式计算方案。

Pandas 的学习曲线虽然陡峭,但只要有清晰的操作地图与实战锻造,很快便能从生疏走向自如。建议读者将本文作为速查手册,在真实项目中有针对性地查询与巩固。