目录
- 环境准备
- 创建 DataFrame
- 查看数据
- 数据选择与过滤
- 选择列
- 选择行
- 结合条件选择
- 数据清洗
- 处理缺失值
- 处理重复数据
- 数据类型转换
- 数据修改与新增
- 新增列
- 修改列名
- 删除列/行
- 数据分组与聚合
- 数据合并
- 数据排序
- 数据统计与计算
- 时间序列操作
- 数据导出
环境准备
确保你已经安装了 Pandas 和 NumPy 库,如果没有,请使用 pip 安装:

pip install pandas numpy
然后在 Python 脚本或 Jupyter Notebook 中导入它们:
import pandas as pd import numpy as np
创建 DataFrame
创建 DataFrame 的最常见方式是使用字典。
# 使用字典创建
data = {
'姓名': ['张三', '李四', '王五', '赵六', '张三'],
'年龄': [25, 30, 28, 35, 25],
'城市': ['北京', '上海', '广州', '深圳', '北京'],
'薪资': [8000, 12000, 10000, 15000, 8500]
}
df = pd.DataFrame(data)
print(df)
输出:
姓名 年龄 城市 薪资
0 张三 25 北京 8000
1 李四 30 上海 12000
2 王五 28 广州 10000
3 赵六 35 深圳 15000
4 张三 25 北京 8500
查看数据
掌握如何快速查看数据是进行后续操作的基础。
# 查看前5行 print(df.head()) # 查看后3行 print(df.tail(3)) # 查看数据的行数和列数 print(df.shape) # 输出: (5, 4) # 查看列名 print(df.columns) # 查看数据类型和内存信息 print(df.info()) # 查看数值型列的描述性统计 print(df.describe())
数据选择与过滤
这是最常用的操作之一。
选择列
# 选择单列,返回一个 Series name_series = df['姓名'] print(type(name_series)) # 选择多列,返回一个新的 DataFrame subset_df = df[['姓名', '薪资']] print(subset_df)
选择行
主要通过 .loc[] (基于标签) 和 .iloc[] (基于整数位置) 来实现。
# 使用 .loc[] 选择行 (通过索引标签) # 选择索引为 1 和 3 的行 print(df.loc[[1, 3]]) # 使用 .iloc[] 选择行 (通过整数位置) # 选择第 2 行和第 4 行 (从0开始计数) print(df.iloc[[1, 3]]) # 选择连续的行 print(df.iloc[0:3]) # 包含 0, 1, 2 行
结合条件选择 (非常强大!)
这是数据分析的精髓,通常使用布尔索引。
# 单条件:筛选年龄大于30的人
print(df[df['年龄'] > 30])
# 多条件:筛选年龄大于30且在北京的人
# 注意:括号和 & (与), | (或), ~ (非) 的使用
print((df['年龄'] > 30) & (df['城市'] == '北京')) # 先得到布尔 Series
print(df[(df['年龄'] > 30) & (df['城市'] == '北京')]) # 再用布尔 Series 筛选
# 使用 .query() 方法 (语法更清晰)
print(df.query('年龄 > 30 and 城市 == "北京"'))
数据清洗
真实世界的数据往往不完美,清洗是必要步骤。
处理缺失值
# 创建一个带有缺失值的 DataFrame
df_with_nan = df.copy()
df_with_nan.loc[2, '薪资'] = np.nan
df_with_nan.loc[4, '年龄'] = np.nan
print("原始数据:")
print(df_with_nan)
# 1. 检查缺失值
print(df_with_nan.isnull().sum())
# 2. 删除含有缺失值的行
df_dropped = df_with_nan.dropna()
print("\n删除缺失值后的数据:")
print(df_dropped)
# 3. 填充缺失值
# 用固定值填充
df_filled_const = df_with_nan.fillna(0)
# 用列的平均值填充
df_filled_mean = df_with_nan.fillna(df_with_nan['薪资'].mean())
print("\n用平均值填充薪资后的数据:")
print(df_filled_mean)
处理重复数据
# 检查重复行 print(df.duplicated()) # 删除重复行 (保留第一个出现的) df_unique = df.drop_duplicates() print(df_unique) # 根据 '姓名' 和 '年龄' 判断是否重复 df_unique_subset = df.drop_duplicates(subset=['姓名', '年龄']) print(df_unique_subset)
数据类型转换
# 查看当前数据类型
print(df.dtypes)
# 将 '年龄' 列从 int64 转为 float64
df['年龄'] = df['年龄'].astype('float64')
print(df.dtypes)
# 将 '薪资' 列格式化为货币字符串
df['薪资_格式化'] = df['薪资'].apply(lambda x: f"¥{x:,}")
print(df)
数据修改与新增
新增列
可以直接通过赋值操作来新增列。
# 基于现有列计算新增列 df['年薪'] = df['薪资'] * 12 # 使用 apply 函数对列进行复杂操作 df['等级'] = df['薪资'].apply(lambda x: '高' if x > 10000 else '中' if x > 5000 else '低') print(df)
修改列名
# 修改单个列名
df.rename(columns={'姓名': '员工姓名'}, inplace=True)
# 修改多个列名
df.rename(columns={'年龄': '员工年龄', '城市': '所在城市'}, inplace=True)
print(df)
注意:
inplace=True会直接在原 DataFrame 上修改,不返回新对象,推荐不使用inplace,而是将结果赋值给一个新变量,这样代码更清晰、可预测。
删除列/行
# 删除列
df = df.drop('年薪', axis=1) # axis=1 表示按列删除
# 删除行
df = df.drop(4, axis=0) # axis=0 表示按行删除,删除索引为 4 的行
print(df)
数据分组与聚合
这是从数据中提取洞察力的核心操作,类似于 SQL 的 GROUP BY。
# 按 '城市' 分组,计算每个城市的平均薪资
avg_salary_by_city = df.groupby('所在城市')['薪资'].mean()
print(avg_salary_by_city)
# 按 '城市' 分组,计算多个聚合指标
agg_results = df.groupby('所在城市').agg(
平均薪资=('薪资', 'mean'),
最高薪资=('薪资', 'max'),
人数=('员工姓名', 'count')
)
print(agg_results)
数据合并
当需要将多个 DataFrame 组合在一起时使用。
# 创建另一个 DataFrame
df_bonus = pd.DataFrame({
'员工姓名': ['张三', '李四', '王五'],
'奖金': [1000, 2000, 1500]
})
# 使用 merge 进行类似 SQL 的 JOIN 操作
# how='inner' 表示内连接 (只保留两个 DataFrame 都有的键)
df_merged = pd.merge(df, df_bonus, on='员工姓名', how='inner')
print(df_merged)
数据排序
# 按 '薪资' 降序排序 df_sorted = df.sort_values(by='薪资', ascending=False) print(df_sorted) # 先按 '城市' 升序,再按 '薪资' 降序排序 df_sorted_multi = df.sort_values(by=['所在城市', '薪资'], ascending=[True, False]) print(df_sorted_multi)
数据统计与计算
Pandas 提供了丰富的数学和统计函数。
# 计算总和 print(df['薪资'].sum()) # 计算相关系数矩阵 print(df.corr()) # 对列进行逐元素计算 df['薪资_增加10%'] = df['薪资'] * 1.1
时间序列操作
如果数据中包含时间戳,Pandas 的 DatetimeIndex 功能非常强大。
# 创建一个时间序列 DataFrame
date_rng = pd.date_range(start='2025-01-01', end='2025-01-05', freq='D')
df_ts = pd.DataFrame(date_rng, columns=['date'])
df_ts['data'] = np.random.randint(0, 100, size=(5))
# 将 'date' 列转为 datetime 类型
df_ts['date'] = pd.to_datetime(df_ts['date'])
# 将 'date' 设为索引
df_ts = df_ts.set_index('date')
print(df_ts)
# 按时间重采样 (从天重采样到周)
# 'W-MON' 表示每周一
df_resampled = df_ts.resample('W-MON').sum()
print(df_resampled)
数据导出
处理完的数据可以导出为各种格式。
# 导出为 CSV 文件
df.to_csv('output.csv', index=False, encoding='utf-8-sig') # index=False 不保存索引,utf-8-sig 解决Excel中文乱码
# 导出为 Excel 文件
df.to_excel('output.xlsx', sheet_name='员工信息', index=False)
# 导出为 HTML 文件
df.to_html('output.html')
总结与最佳实践
-
链式操作: Pandas 的方法大多返回一个新的 DataFrame,这使得链式操作非常方便,代码更简洁。
# 不好的写法 df1 = df.drop_duplicates() df1 = df1[df1['年龄'] > 25] df1 = df1.sort_values('薪资') # 好的链式写法 (df.drop_duplicates() .query('年龄 > 25') .sort_values('薪资')) -
避免循环: 尽量不要在 DataFrame 上使用 Python 的
for循环来处理行,Pandas 的向量化操作(如df.apply(),df[df['列名'] > 值],df.groupby())在底层使用 C 语言优化,速度要快几个数量级。 -
善用文档: 遇到任何不清楚的函数或参数,第一时间查阅 Pandas 官方文档,它是学习 Pandas 最权威的资源。
-
理解
.loc,.iloc,.at,.iat:.loc: 基于标签,最常用,推荐使用。.iloc: 基于整数位置,在明确知道行/列位置时使用。.at:.loc的快速版,用于访问单个标量值。.iat:.iloc的快速版,用于访问单个标量值。
掌握了以上这些操作,你就可以应对绝大多数的数据处理和分析任务了,祝你学习愉快!
