掌握 Python Pandas:从入门到精通
在数据科学和数据分析领域,Python Pandas 库是不可或缺的工具。它提供了高性能、易于使用的数据结构和数据分析工具,是处理结构化数据的首选。本文将带领您从 Pandas 的基础知识入门,逐步深入到高级技术,助您成为一名 Pandas 专家。
I. Pandas 简介 (入门)
1. 什么是 Pandas?
Pandas 是一个开源的 Python 库,用于数据操作和分析。它建立在 NumPy 库之上,提供了快速、灵活且富有表现力的数据结构,旨在使“关系型”或“标记型”数据的工作变得简单直观。
2. 为什么学习 Pandas?
- 高效处理结构化数据:Pandas 的核心数据结构 DataFrame 完美适配表格数据(如 Excel 表、SQL 数据库表)。
- 强大的数据清洗和预处理能力:轻松处理缺失值、重复数据、异常值等。
- 灵活的数据操作:包括数据筛选、排序、分组、聚合、合并等。
- 与其它库的无缝集成:可与 Matplotlib、Seaborn 进行数据可视化,与 Scikit-learn 等库进行机器学习预处理。
- 数据科学家和分析师的必备技能:广泛应用于金融、统计、社会科学、工程等领域。
3. 环境设置
首先,确保您已安装 Python。然后,可以通过 pip 安装 Pandas:
bash
pip install pandas
在您的 Python 脚本或 Jupyter Notebook 中,通常会按以下约定导入 Pandas:
python
import pandas as pd
II. Pandas 基础:核心数据结构与操作 (入门)
Pandas 主要引入了两种核心数据结构:Series 和 DataFrame。
1. Series
Series 是一种一维带标签的数组,可以存储任何数据类型(整数、浮点数、字符串、Python 对象等)。它由两部分组成:数据和与之关联的标签(索引)。
创建 Series:
“`python
import pandas as pd
从列表创建
s = pd.Series([1, 3, 5, 7, 9])
print(“从列表创建的 Series:\n”, s)
从字典创建,键作为索引
s_dict = pd.Series({‘a’: 10, ‘b’: 20, ‘c’: 30})
print(“\n从字典创建的 Series:\n”, s_dict)
带有自定义索引
s_indexed = pd.Series([100, 200, 300], index=[‘x’, ‘y’, ‘z’])
print(“\n带有自定义索引的 Series:\n”, s_indexed)
“`
2. DataFrame
DataFrame 是一个二维的、表格型的数据结构,可以看作是 Series 对象的集合,它们共享相同的索引。它类似于电子表格、SQL 表或字典 Series 的对象。
创建 DataFrame:
“`python
从字典创建 DataFrame
data = {
‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’],
‘Age’: [25, 30, 35, 28],
‘City’: [‘New York’, ‘London’, ‘Paris’, ‘Tokyo’]
}
df = pd.DataFrame(data)
print(“从字典创建的 DataFrame:\n”, df)
带有自定义索引
df_indexed = pd.DataFrame(data, index=[‘A’, ‘B’, ‘C’, ‘D’])
print(“\n带有自定义索引的 DataFrame:\n”, df_indexed)
“`
3. 数据输入与输出 (I/O)
Pandas 提供了强大的功能来读取和写入各种数据格式。
读取数据:
“`python
读取 CSV 文件
df_csv = pd.read_csv(‘your_file.csv’)
读取 Excel 文件
df_excel = pd.read_excel(‘your_file.xlsx’)
读取 JSON 文件
df_json = pd.read_json(‘your_file.json’)
**写入数据:**python
将 DataFrame 写入 CSV 文件
df.to_csv(‘output.csv’, index=False) # index=False 避免写入索引
将 DataFrame 写入 Excel 文件
df.to_excel(‘output.xlsx’, index=False)
“`
4. 基本数据检查与探索
加载数据后,第一步通常是快速查看和理解数据。
“`python
查看前几行数据 (默认前5行)
print(“\nDataFrame 的前3行:\n”, df.head(3))
查看后几行数据 (默认后5行)
print(“\nDataFrame 的后2行:\n”, df.tail(2))
获取 DataFrame 的摘要信息 (非空值数量、数据类型、内存使用等)
print(“\nDataFrame 的信息摘要:”)
df.info()
获取数值列的统计摘要 (均值、标准差、最小值、最大值、四分位数等)
print(“\n数值列的统计摘要:\n”, df.describe())
获取 DataFrame 的形状 (行数, 列数)
print(“\nDataFrame 的形状:”, df.shape)
获取所有列名
print(“\nDataFrame 的列名:”, df.columns)
获取所有列的数据类型
print(“\nDataFrame 的数据类型:\n”, df.dtypes)
“`
5. 数据选择与筛选
- 选择列:
“`python
选择单列 (返回 Series)
name_column = df[‘Name’]
print(“\n选择 ‘Name’ 列:\n”, name_column)
选择多列 (返回 DataFrame)
name_city_columns = df[[‘Name’, ‘City’]]
print(“\n选择 ‘Name’ 和 ‘City’ 列:\n”, name_city_columns)
- **选择行:**python
- `.loc[]`:基于标签(索引名称和列名)选择。
- `.iloc[]`:基于整数位置选择。
使用 .loc[] 选择行 (基于索引标签)
print(“\n使用 .loc[] 选择第一行 (索引0):\n”, df.loc[0])
print(“\n使用 .loc[] 选择多行 (索引0到2):\n”, df.loc[0:2]) # 包含结束索引
使用 .iloc[] 选择行 (基于整数位置)
print(“\n使用 .iloc[] 选择第一行 (位置0):\n”, df.iloc[0])
print(“\n使用 .iloc[] 选择多行 (位置0到2,不包含2):\n”, df.iloc[0:2])
- **条件筛选:**python
筛选 Age 大于 30 的数据
older_than_30 = df[df[‘Age’] > 30]
print(“\nAge 大于 30 的数据:\n”, older_than_30)
多条件筛选 (使用 & 表示且,| 表示或)
london_or_alice = df[(df[‘City’] == ‘London’) | (df[‘Name’] == ‘Alice’)]
print(“\n居住在 London 或名为 Alice 的数据:\n”, london_or_or_alice)
“`
III. 数据操作与清洗 (中级)
1. 处理缺失数据
缺失值是真实世界数据中常见的问题。Pandas 提供了多种处理策略。
“`python
import numpy as np
创建一个带有缺失值的 DataFrame
df_missing = pd.DataFrame({
‘A’: [1, 2, np.nan, 4],
‘B’: [5, np.nan, np.nan, 8],
‘C’: [9, 10, 11, 12]
})
print(“\n原始带有缺失值的 DataFrame:\n”, df_missing)
检查缺失值 (返回布尔型 DataFrame)
print(“\n缺失值检查:\n”, df_missing.isnull())
统计每列的缺失值数量
print(“\n每列的缺失值数量:\n”, df_missing.isnull().sum())
删除含有缺失值的行
df_dropna_rows = df_missing.dropna()
print(“\n删除含有缺失值的行:\n”, df_dropna_rows)
删除含有缺失值的列
df_dropna_cols = df_missing.dropna(axis=1) # axis=1 表示列
print(“\n删除含有缺失值的列:\n”, df_dropna_cols)
填充缺失值
用特定值填充
df_fill_zero = df_missing.fillna(0)
print(“\n用 0 填充缺失值:\n”, df_fill_zero)
用列的均值填充
df_fill_mean = df_missing.fillna(df_missing[‘A’].mean())
print(“\n用列 A 的均值填充:\n”, df_fill_mean)
用前一个有效值填充 (forward fill)
df_fill_ffill = df_missing.fillna(method=’ffill’)
print(“\n用前一个有效值填充 (ffill):\n”, df_fill_ffill)
用后一个有效值填充 (backward fill)
df_fill_bfill = df_missing.fillna(method=’bfill’)
print(“\n用后一个有效值填充 (bfill):\n”, df_fill_bfill)
“`
2. 处理重复数据
“`python
创建一个带有重复数据的 DataFrame
df_duplicates = pd.DataFrame({
‘col1’: [‘A’, ‘B’, ‘A’, ‘C’],
‘col2’: [1, 2, 1, 3]
})
print(“\n原始带有重复值的 DataFrame:\n”, df_duplicates)
查找重复行 (默认查找所有列都重复的行)
print(“\n查找重复行:\n”, df_duplicates.duplicated())
删除重复行 (默认保留第一个出现的值)
df_no_duplicates = df_duplicates.drop_duplicates()
print(“\n删除重复行:\n”, df_no_duplicates)
删除指定列重复的行
df_no_duplicates_col1 = df_duplicates.drop_duplicates(subset=[‘col1’])
print(“\n删除 col1 列重复的行:\n”, df_no_duplicates_col1)
“`
3. 应用函数 (Apply)
apply() 方法非常强大,可以对 Series 或 DataFrame 的行/列应用自定义函数。
“`python
对 Series 应用函数
df[‘Age_ doubled’] = df[‘Age’].apply(lambda x: x * 2)
print(“\n年龄翻倍:\n”, df)
对 DataFrame 的行或列应用函数 (axis=0 for columns, axis=1 for rows)
def get_name_and_age(row):
return f”{row[‘Name’]} is {row[‘Age’]} years old.”
df[‘Description’] = df.apply(get_name_and_age, axis=1)
print(“\n添加描述列:\n”, df)
“`
4. 分组与聚合 (Groupby)
groupby() 是 Pandas 中最常用的功能之一,它实现了“分割-应用-合并”策略,常用于数据汇总和分析。
“`python
data_sales = {
‘Region’: [‘East’, ‘West’, ‘East’, ‘West’, ‘East’],
‘Product’: [‘A’, ‘B’, ‘A’, ‘C’, ‘B’],
‘Sales’: [100, 150, 120, 200, 130]
}
df_sales = pd.DataFrame(data_sales)
print(“\n原始销售数据:\n”, df_sales)
按 Region 分组并计算总销售额
regional_sales = df_sales.groupby(‘Region’)[‘Sales’].sum()
print(“\n按区域划分的总销售额:\n”, regional_sales)
按多个列分组并计算多种聚合
multi_group = df_sales.groupby([‘Region’, ‘Product’])[‘Sales’].agg([‘sum’, ‘mean’, ‘count’])
print(“\n按区域和产品划分的销售额统计:\n”, multi_group)
“`
5. 合并与连接数据 (Merge, Join, Concat)
当需要组合多个 DataFrame 时,Pandas 提供了 concat、merge 和 join。
pd.concat():沿一个轴堆叠 DataFrame。pd.merge():基于一个或多个键,以 SQL 样式连接 DataFrame。.join():在索引或列上连接另一个 DataFrame。
“`python
df1 = pd.DataFrame({‘key’: [‘A’, ‘B’, ‘C’, ‘D’], ‘value’: [1, 2, 3, 4]})
df2 = pd.DataFrame({‘key’: [‘B’, ‘D’, ‘E’, ‘F’], ‘value’: [5, 6, 7, 8]})
使用 pd.concat 堆叠 DataFrame
df_concat = pd.concat([df1, df2])
print(“\n使用 concat 堆叠:\n”, df_concat)
使用 pd.merge 合并 DataFrame (默认内连接)
df_merge_inner = pd.merge(df1, df2, on=’key’, suffixes=(‘_left’, ‘_right’))
print(“\n使用 merge (内连接):\n”, df_merge_inner)
使用 pd.merge 合并 DataFrame (外连接)
df_merge_outer = pd.merge(df1, df2, on=’key’, how=’outer’, suffixes=(‘_left’, ‘_right’))
print(“\n使用 merge (外连接):\n”, df_merge_outer)
“`
IV. 高级 Pandas 技术 (精通)
1. 处理时间序列数据
Pandas 在处理时间序列数据方面表现出色。
“`python
创建一个时间序列 Series
rng = pd.date_range(‘1/1/2023′, periods=5, freq=’D’)
ts = pd.Series(np.random.randn(len(rng)), index=rng)
print(“\n时间序列 Series:\n”, ts)
时间序列索引和选择
print(“\n特定日期的值:\n”, ts[‘2023-01-03’])
print(“\n日期范围选择:\n”, ts[‘2023-01-02′:’2023-01-04’])
重采样 (Resampling)
将每日数据重采样为每月均值
monthly_mean = ts.resample(‘M’).mean()
print(“\n重采样为每月均值:\n”, monthly_mean)
“`
2. 分类数据 (Categorical Data)
分类数据类型可以大大节省内存并提高某些操作的性能,尤其适用于具有有限数量的唯一值(如性别、国家、产品类别)的列。
python
df_category = pd.DataFrame({'gender': ['male', 'female', 'male', 'female', 'male']})
df_category['gender'] = df_category['gender'].astype('category')
print("\n分类数据类型:\n", df_category['gender'].dtype)
3. 高级索引 (MultiIndex)
MultiIndex(分层索引)允许您在轴上拥有多个索引级别,可以处理更复杂的数据结构。
“`python
创建 MultiIndex
index = pd.MultiIndex.from_product([[‘A’, ‘B’], [1, 2]], names=[‘level1’, ‘level2’])
data_multi = pd.Series(np.random.randn(4), index=index)
print(“\nMultiIndex Series:\n”, data_multi)
从 MultiIndex Series 转换为 DataFrame
df_multi = data_multi.unstack()
print(“\nMultiIndex DataFrame (unstack):\n”, df_multi)
使用 .loc 访问 MultiIndex 数据
print(“\n访问 level1 为 ‘A’ 的数据:\n”, data_multi.loc[‘A’])
print(“\n访问 level1 为 ‘A’ 且 level2 为 2 的数据:\n”, data_multi.loc[(‘A’, 2)])
“`
4. 性能优化
对于大型数据集,性能优化至关重要。
- 避免循环:尽可能使用 Pandas 的内置向量化操作或
apply()。 - 使用
at和iat:对于单个元素的快速访问,比loc和iloc更快。 eval()和query():用于对 DataFrame 进行复杂表达式计算和筛选,可显著提高性能。
“`python
使用 query 进行条件筛选 (通常比 df[df[‘col’] > value] 更快)
df_filtered_query = df.query(‘Age > 30’)
“`
– Copy-on-Write (CoW):Pandas 3.0 引入了 CoW 优化,可以减少不必要的数据复制,提高性能。
5. 文本数据处理
使用 .str 访问器可以对 Series 中的字符串数据执行各种操作。
“`python
df_text = pd.DataFrame({‘text_col’: [‘ hello world ‘, ‘ Python Pandas ‘, ‘ data science ‘]})
转换为小写并去除首尾空格
df_text[‘processed_text’] = df_text[‘text_col’].str.lower().str.strip()
print(“\n处理后的文本数据:\n”, df_text)
检查是否包含特定子字符串
df_text[‘contains_python’] = df_text[‘text_col’].str.contains(‘Python’, case=False)
print(“\n是否包含 ‘Python’:\n”, df_text)
“`
6. 与其它库集成
Pandas 与数据可视化库 Matplotlib 和 Seaborn 紧密集成。
“`python
import matplotlib.pyplot as plt
df[‘Age’].plot(kind=’hist’)
plt.title(‘Distribution of Age’)
plt.show()
“`
V. 总结与展望
掌握 Python Pandas 是成为一名优秀数据专业人员的关键一步。从理解 Series 和 DataFrame 的基本概念,到熟练运用数据清洗、转换、分组和合并技术,再到深入探索时间序列、分类数据和性能优化,您将能够高效地处理各种复杂的数据挑战。
下一步:
– 实践,实践,再实践:在真实的 Kaggle 数据集或您自己的项目中运用这些技能。
– 查阅官方文档:Pandas 官方文档是最好的学习资源之一,包含大量示例和详细说明。
– 探索高级主题:如 Dask、Modin 等用于处理超大型数据集的库,它们与 Pandas API 兼容。
通过持续学习和实践,您将能够充分发挥 Pandas 的强大功能,为您的数据分析和数据科学工作赋能。