目录
- 准备工作:安装与导入
- 创建 DataFrame
- 查看数据
- 数据选择与过滤
- 数据清洗
- 数据操作
- 添加/删除列
- 排序
- 分组聚合
- 数据合并
- 数据透视与重塑
- 数据导出与导入
- 实战案例:一个完整的数据处理流程
准备工作:安装与导入
你需要确保已经安装了 Pandas 和它的核心依赖 NumPy。

pip install pandas numpy
在 Python 脚本或 Jupyter Notebook 中,通常这样导入:
import pandas as pd import numpy as np
创建 DataFrame
DataFrame 是一个二维的、带标签的、大小可变的数据结构,类似于 Excel 表格或 SQL 表。
从字典创建 这是最常见的方式,键是列名,值是列数据。
data = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 28, 35],
'城市': ['北京', '上海', '广州', '深圳'],
'薪资': [8000, 12000, 10000, 15000]
}
df = pd.DataFrame(data)
print(df)
从 NumPy 数组创建 可以指定行索引和列索引。

data = np.random.rand(4, 3) # 4行3列的随机数
df_array = pd.DataFrame(data,
index=['row1', 'row2', 'row3', 'row4'],
columns=['col_A', 'col_B', 'col_C'])
print(df_array)
查看数据
当你拿到一个 DataFrame 时,首先需要了解它的基本情况。
df.head(n): 查看前n行数据,默认是 5 行。df.tail(n): 查看后n行数据。df.info(): 查看 DataFrame 的整体信息,包括列名、非空值数量、数据类型和内存占用。这是最常用的信息查看方法!df.describe(): 生成描述性统计信息,包括计数、均值、标准差、最小值、最大值等,主要用于数值型列。df.shape: 返回一个元组,表示 DataFrame 的行数和列数。df.columns: 返回列名列表。df.index: 返回行索引列表。
# 假设使用上面创建的 df
print("--- 前3行 ---")
print(df.head(3))
print("\n--- 基本信息 ---")
df.info()
print("\n--- 描述性统计 ---")
print(df.describe())
print("\n--- 形状 (行, 列) ---")
print(df.shape)
print("\n--- 列名 ---")
print(df.columns)
数据选择与过滤
选择数据是数据分析的核心操作。
选择列
- 使用列名字符串:
df['列名']或df.列名(如果列名没有空格且是合法的变量名)。
# 选择单列 name_series = df['姓名'] print(type(name_series)) # 返回的是一个 Series # 选择多列 subset_df = df[['姓名', '薪资']] # 注意,这里需要用两层方括号,返回的是 DataFrame print(subset_df)
选择行
- 使用
.loc[]:基于进行选择。df.loc[行标签, 列标签] - 使用
.iloc[]:基于整数位置进行选择。df.iloc[行索引, 列索引]
# 使用 .loc
print("--- 使用 .loc 选择第一行 ---")
print(df.loc[0]) # 行标签是 0
print("\n--- 使用 .loc 选择第一行的'姓名'和'城市' ---")
print(df.loc[0, ['姓名', '城市']])
# 使用 .iloc
print("\n--- 使用 .iloc 选择第一行 ---")
print(df.iloc[0])
print("\n--- 使用 .iloc 选择第一行的'姓名'和'城市' ---")
print(df.iloc[0, [0, 2]]) # '姓名'在第0列,'城市'在第2列
条件过滤 (布尔索引)
这是最强大的过滤方式。
# 筛选年龄大于30的人 older_than_30 = df[df['年龄'] > 30] print(older_than_30) # 筛选城市是上海且薪资大于10000的人 shanghai_high_salary = df[(df['城市'] == '上海') & (df['薪资'] > 10000)] print(shanghai_high_salary) # 使用 | 表示 "或" # 筛选年龄小于28或者城市是北京的人 young_or_beijing = df[(df['年龄'] < 28) | (df['城市'] == '北京')] print(young_or_beijing)
数据清洗
真实世界的数据总是不完美的,清洗是必不可少的一步。

处理缺失值
df.isnull().sum(): 查看每列的缺失值数量。df.dropna(): 删除含有缺失值的行或列。df.fillna(value): 用指定的值填充缺失值。
# 创建一个有缺失值的 DataFrame
df_with_nan = df.copy()
df_with_nan.loc[1, '薪资'] = np.nan
df_with_nan.loc[3, '城市'] = None # Pandas 会将 None 自动识别为 NaN
print("--- 带有缺失值的 DataFrame ---")
print(df_with_nan)
print("\n--- 每列缺失值数量 ---")
print(df_with_nan.isnull().sum())
# 删除含有缺失值的行
df_dropped = df_with_nan.dropna()
print("\n--- 删除含有缺失值的行后 ---")
print(df_dropped)
# 用均值填充薪资的缺失值
mean_salary = df_with_nan['薪资'].mean()
df_filled = df_with_nan.fillna({'薪资': mean_salary})
print("\n--- 用均值填充薪资后 ---")
print(df_filled)
处理重复值
df.duplicated(): 检查是否有重复行。df.drop_duplicates(): 删除重复行。
df_with_dup = df.append(df.loc[0]) # 添加一行重复数据
print("--- 带有重复行的 DataFrame ---")
print(df_with_dup)
print("\n--- 删除重复行后 ---")
print(df_with_dup.drop_duplicates())
数据操作
添加/删除列
- 直接赋值:
df['新列名'] = ... df.drop(): 删除列或行。axis=1表示按列删除,axis=0表示按行删除。
# 添加一个新列 '级别'
df['级别'] = ['初级', '高级', '中级', '专家']
print("--- 添加新列后 ---")
print(df)
# 删除 '城市' 列
df_dropped_col = df.drop('城市', axis=1)
print("\n--- 删除'城市'列后 ---")
print(df_dropped_col)
排序
df.sort_values(): 按值排序。by: 指定排序列。ascending=True/False: 升序或降序。inplace=True/False: 是否在原 DataFrame 上修改。
# 按'年龄'降序排序
df_sorted = df.sort_values(by='年龄', ascending=False)
print("--- 按'年龄'降序排序 ---")
print(df_sorted)
# 按'薪资'升序,'年龄'降序排序(多级排序)
df_multi_sorted = df.sort_values(by=['薪资', '年龄'], ascending=[True, False])
print("\n--- 按'薪资'升序、'年龄'降序排序 ---")
print(df_multi_sorted)
分组聚合
这是数据分析的利器,类似于 SQL 的 GROUP BY。
df.groupby('列名'): 按指定列进行分组。['列名'].agg(['函数1', '函数2']): 对分组后的数据应用聚合函数。
# 按'城市'分组,计算每个城市的平均薪资
city_avg_salary = df.groupby('城市')['薪资'].mean()
print("--- 各城市平均薪资 ---")
print(city_avg_salary)
# 按'城市'分组,计算薪资的总和和人数
city_stats = df.groupby('城市')['薪资'].agg(['sum', 'count'])
print("\n--- 各城市薪资总和与人数 ---")
print(city_stats)
数据合并
pd.concat(): 用于堆叠 DataFrame,可以按行或按列拼接。pd.merge(): 用于数据库风格的合并,类似于 SQL 的JOIN。
# 创建两个 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value1': [1, 2, 3, 4]})
df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value2': [5, 6, 7, 8]})
# 按 行 堆叠
concat_df = pd.concat([df1, df2], axis=0)
print("--- 按 行 堆叠 ---")
print(concat_df)
# 按 列 合并 (类似 SQL 的 FULL OUTER JOIN)
merged_df = pd.merge(df1, df2, on='key', how='outer')
print("\n--- 按'key'列合并 (OUTER JOIN) ---")
print(merged_df)
# 按 列 合并 (类似 SQL 的 INNER JOIN)
merged_inner_df = pd.merge(df1, df2, on='key', how='inner')
print("\n--- 按'key'列合并 (INNER JOIN) ---")
print(merged_inner_df)
数据透视与重塑
df.pivot_table(): 创建数据透视表,非常方便进行交叉分析。df.melt(): 将宽格式的数据“融化”成长格式。
# 创建一个适合透视的 DataFrame
sales_data = {
'月份': ['一月', '一月', '一月', '二月', '二月', '二月'],
'产品': ['A', 'B', 'C', 'A', 'B', 'C'],
'销售额': [100, 150, 200, 120, 180, 210]
}
sales_df = pd.DataFrame(sales_data)
# 创建透视表:按月份和产品分组,计算销售额总和
pivot_table = sales_df.pivot_table(index='月份', columns='产品', values='销售额', aggfunc='sum')
print("--- 销售额透视表 ---")
print(pivot_table)
# 将宽格式融化成长格式
melted_df = pivot_table.reset_index().melt(id_vars='月份', var_name='产品', value_name='销售额')
print("\n--- 融化后的长格式数据 ---")
print(melted_df)
数据导出与导入
Pandas 支持多种格式的读写。
# 导出为 CSV 文件
df.to_csv('output.csv', index=False, encoding='utf-8-sig') # index=False 不写入行索引
# 从 CSV 文件导入
df_from_csv = pd.read_csv('output.csv')
print("--- 从 CSV 读取的数据 ---")
print(df_from_csv)
# 导出为 Excel 文件
df.to_excel('output.xlsx', sheet_name='员工信息', index=False)
# 从 Excel 文件导入
df_from_excel = pd.read_excel('output.xlsx', sheet_name='员工信息')
print("\n--- 从 Excel 读取的数据 ---")
print(df_from_excel)
实战案例:一个完整的数据处理流程
假设我们有一个销售数据文件 sales.csv如下:
Date,Product,Region,Sales,Units
2025-01-01,Apple,North,1000,100
2025-01-01,Apple,South,1200,120
2025-01-01,Banana,North,800,200
2025-01-01,Banana,South,900,225
2025-01-02,Apple,North,1100,110
2025-01-02,Apple,South,1300,130
2025-01-02,Banana,North,850,212
2025-01-02,Banana,South,950,237
2025-01-03,Apple,North,1050,105
2025-01-03,Apple,South,1250,125
2025-01-03,Banana,North,820,205
2025-01-03,Banana,South,980,245
目标:
- 读取数据。
- 查看“香蕉”在“北部”地区的总销售额和平均销售额。
- 计算每个产品的平均单价 (
Sales / Units)。 - 找出销售额最高的那一天。
# 1. 读取数据
sales_df = pd.read_csv('sales.csv')
print("--- 原始数据 ---")
print(sales_df.head())
# 2. 筛选香蕉在北部地区的销售数据
banana_north_sales = sales_df[(sales_df['Product'] == 'Banana') & (sales_df['Region'] == 'North')]
total_banana_north_sales = banana_north_sales['Sales'].sum()
avg_banana_north_sales = banana_north_sales['Sales'].mean()
print(f"\n--- 香蕉在北部地区的总销售额: {total_banana_north_sales}, 平均销售额: {avg_banana_north_sales:.2f} ---")
# 3. 计算每个产品的平均单价
sales_df['Unit_Price'] = sales_df['Sales'] / sales_df['Units']
avg_price_per_product = sales_df.groupby('Product')['Unit_Price'].mean()
print("\n--- 各产品平均单价 ---")
print(avg_price_per_product)
# 4. 找出销售额最高的那一天
max_sales_row = sales_df.loc[sales_df['Sales'].idxmax()]
print("\n--- 销售额最高的那一天 ---")
print(max_sales_row)
这个案例涵盖了读取、过滤、计算、分组和查找极值等核心操作,是 Pandas 应用的一个缩影。
掌握 Pandas DataFrame 是数据科学和分析的基石,建议你:
- 多动手实践:尝试用上面的例子操作你自己的数据。
- 查阅官方文档:Pandas Documentation 是最权威、最全面的参考资料。
- 善用搜索引擎:遇到具体问题,直接搜索 "pandas how to do X" 通常能找到解决方案。
希望这份详细的指南能帮助你快速上手 Python DataFrame 处理!
