Pandas 入门指南 – wiki基地


Pandas 入门指南:数据分析的得力助手

在当今数据驱动的世界里,有效地处理、分析和理解数据是许多领域的核心技能。无论你是数据科学家、数据分析师、工程师,还是对数据感兴趣的学生,掌握强大的数据处理工具都至关重要。在 Python 的生态系统中,Pandas 库无疑是数据处理和分析领域的王者。

Pandas 提供了一套快速、灵活且富有表现力的数据结构,旨在让使用“关系型”或“带标签的”数据变得简单直观。它是构建在 NumPy 库之上,并在数据清洗、转换、合并、切片、聚合等方面提供了丰富的功能。本文将带你从零开始,逐步认识和使用 Pandas 这个强大的工具。

我们将涵盖以下内容:

  1. Pandas 是什么?为什么选择 Pandas?
  2. 安装 Pandas
  3. Pandas 的核心数据结构:Series 和 DataFrame
    • 理解 Series
    • 理解 DataFrame
  4. 创建 Series 和 DataFrame
    • 从列表/NumPy 数组创建
    • 从字典创建
    • 从文件读取数据 (CSV, Excel)
  5. 查看数据
    • .head(), .tail(), .info(), .describe(), .shape
  6. 数据选择与索引
    • 列选择
    • 行选择 (.loc.iloc 的区别与使用)
    • 布尔索引 (条件筛选)
  7. 基本数据操作
    • 添加、删除、修改列
    • 重命名列和索引
    • 处理缺失数据 (.isnull(), .notnull(), .dropna(), .fillna())
    • 数据类型转换 (.astype())
  8. 数据排序
    • 按值排序 (.sort_values())
    • 按索引排序 (.sort_index())
  9. 数据分组与聚合 (.groupby())
  10. 数据合并 (.merge())
  11. 数据输出
    • 保存到文件 (CSV, Excel)
  12. 总结与展望

1. Pandas 是什么?为什么选择 Pandas?

Pandas 是什么?

Pandas 是一个开源的 Python 库,专注于提供高性能、易于使用的数据结构和数据分析工具。它的名字来源于 “Panel Data”(面板数据)和 “Python Data Analysis”(Python 数据分析)。

为什么选择 Pandas?

  • 强大的数据结构: Pandas 引入了 SeriesDataFrame,它们是处理各种类型数据的理想工具,尤其适用于表格数据(如数据库表、电子表格)。
  • 数据清洗与准备: 现实世界的数据往往是混乱、不完整或格式不统一的。Pandas 提供了丰富的功能来处理缺失值、异常值、重复项,进行数据转换、格式化等,极大地简化了数据清洗过程。
  • 数据探索与分析: 可以轻松地进行数据切片、切块、聚合、分组、合并、连接等操作,快速获得数据的概览、统计信息和洞察。
  • 灵活的输入输出: 支持从多种文件格式读取数据(CSV, Excel, SQL 数据库, JSON, HDF5 等)并将处理后的数据输出到这些格式。
  • 集成性好: 与 Python 生态系统中的其他库(如 NumPy, Matplotlib, Scikit-learn)紧密集成,方便进行科学计算、数据可视化和机器学习。
  • 性能高效: 底层使用 NumPy 实现,处理大量数据时性能通常比较出色。

总而言之,如果你需要在 Python 中进行数据加载、清洗、转换、分析和可视化准备,Pandas 是你的首选工具。

2. 安装 Pandas

安装 Pandas 非常简单。如果你已经安装了 Python 和包管理器 pip,可以通过命令行执行:

bash
pip install pandas

如果你使用的是 Anaconda 发行版,Pandas 通常已经预装好了。如果需要更新或确保安装,可以使用 conda:

bash
conda install pandas

安装完成后,在 Python 脚本或交互式环境中,通常会按照约定俗成的惯例将其导入为 pd

python
import pandas as pd
import numpy as np # Pandas 很多功能依赖 NumPy,通常也一起导入

接下来,我们将深入了解 Pandas 的核心。

3. Pandas 的核心数据结构:Series 和 DataFrame

Pandas 的核心是其两种主要的数据结构:Series 和 DataFrame。理解它们是掌握 Pandas 的关键。

理解 Series

Series 可以被看作是一种带有标签的一维数组。它类似于 NumPy 的一维数组,但额外提供了索引(label),使得可以通过标签来访问数据。

  • 数据 (Values): Series 包含一组数据,可以是任意的数据类型(整数、浮点数、字符串、Python 对象等)。
  • 索引 (Index): Series 包含一个与之关联的索引,为每个数据点提供一个标签。如果没有显式指定索引,Pandas 会自动创建一个从 0 开始的默认整数索引。

你可以想象 Series 就像电子表格中的一列数据,其中索引是行号或行标签。

示例:

“`python
import pandas as pd

创建一个简单的 Series

s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(s)
“`

输出解释:

0 1.0
1 3.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64

左边的数字(0, 1, 2, 3, 4, 5)是默认的索引。右边是对应的数据值。np.nan 表示缺失值。dtype: float64 表示 Series 中数据的数据类型。

你可以通过索引访问 Series 中的元素:

python
print(s[0]) # 访问索引为 0 的元素
print(s[:3]) # 访问前三个元素 (切片)

你也可以创建带有自定义索引的 Series:

python
s2 = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print(s2)
print(s2['b']) # 通过自定义索引访问

输出解释:

“`
a 10
b 20
c 30
d 40
dtype: int64

20 # 通过自定义索引访问 ‘b’ 对应的值
“`

理解 DataFrame

DataFrame 是 Pandas 中最重要也是最常用的数据结构。它可以被看作是一个二维的、大小可变的、带有标签的表格数据结构,类似于关系型数据库中的表或电子表格。

  • 数据 (Data): DataFrame 包含按行和列组织的二维数据。
  • 列 (Columns): 每一列都有一个标签(列名),并且每一列本质上都是一个 Series,共享同一个索引。
  • 索引 (Index): DataFrame 有一个行索引,为每一行提供一个标签。同样,如果没有显式指定,会使用从 0 开始的默认整数索引。

你可以将 DataFrame 想象成一个完整的电子表格或数据库表,其中列是不同的字段,行是不同的记录,行索引是记录的唯一标识。

示例:

“`python
import pandas as pd
import numpy as np

创建一个简单的 DataFrame

data = {‘col1’: [1, 2, 3, 4],
‘col2’: [‘A’, ‘B’, ‘C’, ‘D’],
‘col3’: [True, False, True, False]}
df = pd.DataFrame(data)
print(df)
“`

输出解释:

col1 col2 col3
0 1 A True
1 2 B False
2 3 C True
3 4 D False

左边的数字(0, 1, 2, 3)是行索引,顶部的 ‘col1’, ‘col2’, ‘col3’ 是列名。

DataFrame 的强大之处在于它可以容纳不同数据类型的列(因为每列是一个 Series),并且提供了丰富的行和列操作功能。

你可以访问 DataFrame 的列:

python
print(df['col1']) # 访问 'col1' 列,结果是一个 Series
print(type(df['col1']))

你也可以访问 DataFrame 的行(后面会详细介绍使用 .loc.iloc)。

4. 创建 Series 和 DataFrame

了解了核心结构后,我们看看如何创建它们。

从列表/NumPy 数组创建

“`python

创建 Series

s = pd.Series([10, 20, 30])
print(s)

从 NumPy 数组创建 DataFrame

arr = np.random.randn(6, 4) # 创建一个 6×4 的随机数组
dates = pd.date_range(‘20230101’, periods=6) # 创建一个日期索引
df = pd.DataFrame(arr, index=dates, columns=list(‘ABCD’)) # 指定索引和列名
print(df)
“`

从字典创建

字典是创建 Series 和 DataFrame 的常用方式。

“`python

从字典创建 Series (字典的键成为索引)

d = {‘a’: 100, ‘b’: 200, ‘c’: 300}
s3 = pd.Series(d)
print(s3)

从字典创建 DataFrame (字典的键成为列名)

data = {‘col1’: [1, 2, 3], ‘col2’: [‘X’, ‘Y’, ‘Z’]}
df2 = pd.DataFrame(data)
print(df2)

如果字典的值是 Series,可以创建对齐索引的 DataFrame

d2 = {‘col_A’: pd.Series([1, 2, 3], index=[‘x’, ‘y’, ‘z’]),
‘col_B’: pd.Series([4, 5, 6, 7], index=[‘x’, ‘y’, ‘z’, ‘w’])}
df3 = pd.DataFrame(d2) # 会自动对齐索引,没有对应值的会是 NaN
print(df3)
“`

从文件读取数据 (CSV, Excel)

这是实际应用中最常见的创建 DataFrame 的方式。Pandas 提供了 read_csv()read_excel() 等函数。

“`python

假设有一个名为 ‘data.csv’ 的文件

内容可能类似:

id,name,age

1,Alice,30

2,Bob,25

3,Charlie,35

读取 CSV 文件

try:
df_csv = pd.read_csv(‘data.csv’) # 请替换为你的文件路径
print(“\n— 从 CSV 读取的数据 —“)
print(df_csv)
except FileNotFoundError:
print(“\n错误:data.csv 文件未找到。跳过 CSV 读取示例。”)
# 创建一个模拟的 DataFrame 用于后续操作
data_mock = {‘id’: [1, 2, 3, 4, 5],
‘name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eva’],
‘age’: [30, 25, 35, 40, 28],
‘city’: [‘New York’, ‘Los Angeles’, ‘Chicago’, ‘New York’, ‘Los Angeles’],
‘score’: [85.5, 90.2, 78.9, np.nan, 92.1]}
df_csv = pd.DataFrame(data_mock)

假设有一个名为 ‘data.xlsx’ 的文件

读取 Excel 文件 (需要安装 openpyxl 或 xlrd 库:pip install openpyxl)

try:
df_excel = pd.read_excel(‘data.xlsx’) # 请替换为你的文件路径
print(“\n— 从 Excel 读取的数据 —“)
print(df_excel)
except FileNotFoundError:
print(“\n错误:data.xlsx 文件未找到。跳过 Excel 读取示例。”)
except ImportError:
print(“\n错误:读取 Excel 需要安装 openpyxl 或 xlrd。跳过 Excel 读取示例。”)

为了演示,我们使用模拟创建的 df_csv 作为后续的示例数据框 df

df = df_csv.copy()
print(“\n— 用于后续演示的数据框 —“)
print(df)
“`

read_csv()read_excel() 有许多有用的参数,例如:
* sep: 指定分隔符 (默认为逗号,sep='\t' 用于读取 TSV)
* header: 指定哪一行作为列名 (默认为 0,即第一行)
* index_col: 指定哪一列作为行索引
* dtype: 指定列的数据类型
* na_values: 指定哪些值应被视为缺失值 (NaN)

5. 查看数据

创建或加载数据后,你需要查看它以了解其结构和内容。

“`python

查看前几行 (默认为前5行)

print(“\n— df.head() —“)
print(df.head())

查看后几行 (默认为后5行)

print(“\n— df.tail(3) —“)
print(df.tail(3)) # 查看后3行

查看数据框的摘要信息 (列名、非空值数量、数据类型、内存使用等)

print(“\n— df.info() —“)
df.info()

查看数值列的描述性统计信息 (计数、均值、标准差、最小值、最大值、四分位数)

print(“\n— df.describe() —“)
print(df.describe())

查看数据框的形状 (行数, 列数)

print(“\n— df.shape —“)
print(df.shape) # 输出 (行数, 列数)

查看列名

print(“\n— df.columns —“)
print(df.columns)

查看行索引

print(“\n— df.index —“)
print(df.index)

查看数据框的所有值 (返回 NumPy 数组)

print(“\n— df.values —“)
print(df.values)
“`

这些方法能帮助你快速了解数据的大致情况。

6. 数据选择与索引

从 DataFrame 中提取特定行、列或单元格是日常操作中最频繁的任务之一。Pandas 提供了多种方法来实现这一点。

列选择

最简单的方式是使用方括号 [] 和列名。

“`python

选择单列 (返回 Series)

print(“\n— 选择单列 ‘name’ —“)
print(df[‘name’])

选择多列 (返回 DataFrame)

print(“\n— 选择多列 [‘name’, ‘age’] —“)
print(df[[‘name’, ‘age’]])

注意:使用点号 ‘.’ 访问列名也可以,但不推荐用于有空格或特殊字符的列名,且容易与方法名混淆

print(df.name) # 与 df[‘name’] 效果相同,但不推荐

“`

行选择 (.loc.iloc)

选择行通常使用 .loc.iloc。这是 Pandas 中非常重要但也容易混淆的部分。

  • .loc:基于标签 (Label-based) 的索引。 使用行索引标签和列名标签进行选择。
  • .iloc:基于整数位置 (Integer-location based) 的索引。 使用从 0 开始的整数位置进行选择,类似于 Python 列表和 NumPy 数组的索引方式。

使用 .loc (基于标签):

“`python
print(“\n— 使用 .loc 选择行 —“)

选择单行 (通过行索引标签)

print(“选择索引为 0 的行:”)
print(df.loc[0]) # 假设默认索引是整数 0, 1, 2…

选择多行 (通过行索引标签列表)

print(“\n选择索引为 0 和 2 的行:”)
print(df.loc[[0, 2]])

选择指定行索引范围内的行 (注意:loc 的切片是包含结束标签的)

print(“\n选择索引从 1 到 3 的行 (包含 3):”)
print(df.loc[1:3])

同时选择行和列

print(“\n选择索引为 0 和 2 的行的 ‘name’ 和 ‘age’ 列:”)
print(df.loc[[0, 2], [‘name’, ‘age’]])

选择所有行的 ‘name’ 列

print(“\n选择所有行的 ‘name’ 列:”)
print(df.loc[:, ‘name’]) # : 表示所有行

选择索引从 1 到 3 的行的所有列

print(“\n选择索引从 1 到 3 的行的所有列:”)
print(df.loc[1:3, :])
“`

使用 .iloc (基于整数位置):

“`python
print(“\n— 使用 .iloc 选择行 —“)

选择单行 (通过行位置)

print(“选择位置为 0 的行:”)
print(df.iloc[0]) # 第一行

选择多行 (通过行位置列表)

print(“\n选择位置为 0 和 2 的行:”)
print(df.iloc[[0, 2]])

选择指定行位置范围内的行 (注意:iloc 的切片是不包含结束位置的,同 Python 切片)

print(“\n选择位置从 1 到 3 的行 (不包含 3):”)
print(df.iloc[1:3]) # 第二行和第三行 (位置 1 和 2)

同时选择行和列 (使用整数位置)

print(“\n选择位置为 0 和 2 的行的位置为 1 和 2 的列 (‘name’, ‘age’):”)
print(df.iloc[[0, 2], [1, 2]]) # 位置 1 是 ‘name’,位置 2 是 ‘age’

选择所有行的位置为 1 的列

print(“\n选择所有行的位置为 1 的列 (‘name’):”)
print(df.iloc[:, 1]) # : 表示所有行,1 表示第二列

选择位置从 1 到 3 的行的所有列

print(“\n选择位置从 1 到 3 的行的所有列:”)
print(df.iloc[1:3, :])
“`

总结 .loc vs .iloc:

  • .loc: 使用标签(行索引标签,列名)。切片包含结束标签。
  • .iloc: 使用整数位置(从 0 开始)。切片不包含结束位置。

对于使用默认整数索引的 DataFrame,.loc[0].iloc[0] 会选择同一行。但当你使用自定义索引时,它们的行为会不同,务必注意!

布尔索引 (条件筛选)

布尔索引是根据某一列或多列的值来选择行。这非常强大,可以用来过滤数据。

“`python
print(“\n— 布尔索引 (条件筛选) —“)

选择 age 大于 30 的所有行

print(“age 大于 30 的行:”)
print(df[df[‘age’] > 30])

选择 city 是 ‘New York’ 的所有行

print(“\ncity 是 ‘New York’ 的行:”)
print(df[df[‘city’] == ‘New York’])

组合多个条件 (使用 & 表示 ‘与’, | 表示 ‘或’, ~ 表示 ‘非’)

选择 age 大于 30 并且 city 是 ‘New York’ 的行

print(“\nage 大于 30 且 city 是 ‘New York’ 的行:”)
print(df[(df[‘age’] > 30) & (df[‘city’] == ‘New York’)])

选择 age 小于 30 或 city 是 ‘Chicago’ 的行

print(“\nage 小于 30 或 city 是 ‘Chicago’ 的行:”)
print(df[(df[‘age’] < 30) | (df[‘city’] == ‘Chicago’)])

使用 .isin() 方法选择某一列包含在列表中的值

print(“\ncity 是 ‘New York’ 或 ‘Chicago’ 的行:”)
print(df[df[‘city’].isin([‘New York’, ‘Chicago’])])

结合 .loc 进行布尔索引和列选择

print(“\n选择 age 大于 30 的行的 ‘name’ 和 ‘city’ 列:”)
print(df.loc[df[‘age’] > 30, [‘name’, ‘city’]])
“`

7. 基本数据操作

添加、删除、修改列

“`python
print(“\n— 基本数据操作:列 —“)

添加新列

df[‘is_adult’] = df[‘age’] >= 18
print(“\n添加 ‘is_adult’ 列:”)
print(df)

修改现有列的值

df[‘age’] = df[‘age’] + 1 # 所有人的年龄加 1
print(“\n年龄加 1 后:”)
print(df)

删除列

使用 del

del df[‘is_adult’]

print(“\n删除 ‘is_adult’ 列后 (使用 del):”)

print(df)

使用 .drop() 方法 (推荐,因为它更灵活,可以选择删除行或列)

axis=1 表示删除列,axis=0 表示删除行 (axis=0 是默认值)

inplace=True 会直接修改原 DataFrame,否则返回一个新 DataFrame

df_dropped_col = df.drop(‘is_adult’, axis=1) # 返回新 DataFrame
print(“\n删除 ‘is_adult’ 列后 (使用 .drop()):”)
print(df_dropped_col)

删除多列

df_multiple_dropped = df.drop([‘city’, ‘score’], axis=1)
print(“\n删除多列 ‘city’ 和 ‘score’ 后:”)
print(df_multiple_dropped)

注意:为了后续演示,我们恢复 df 到原始状态或使用副本

df = df_csv.copy()
“`

重命名列和索引

使用 .rename() 方法可以修改列名或索引标签。

“`python
print(“\n— 重命名列和索引 —“)

重命名列

df_renamed_cols = df.rename(columns={‘name’: ‘姓名’, ‘age’: ‘年龄’})
print(“\n重命名列名后:”)
print(df_renamed_cols)

重命名索引 (例如,将 id 列设置为索引并重命名索引名)

df_indexed = df.set_index(‘id’) # 将 id 列设置为索引
df_renamed_index = df_indexed.rename(index={1: ‘用户A’, 3: ‘用户C’})
print(“\n重命名索引标签后:”)
print(df_renamed_index)

注意:.rename() 默认返回新的 DataFrame,使用 inplace=True 直接修改原 DataFrame

“`

处理缺失数据 (.isnull(), .notnull(), .dropna(), .fillna())

现实世界的数据中经常存在缺失值 (通常显示为 NaN – Not a Number)。Pandas 提供了方便的方法来识别和处理它们。

“`python
print(“\n— 处理缺失数据 —“)

检查哪些位置是缺失值 (返回布尔型 DataFrame)

print(“\n检查缺失值:”)
print(df.isnull())

检查哪些位置不是缺失值 (返回布尔型 DataFrame)

print(“\n检查非缺失值:”)
print(df.notnull())

计算每列的缺失值数量

print(“\n每列缺失值数量:”)
print(df.isnull().sum())

删除含有缺失值的行或列

axis=0 (默认) 删除含有缺失值的行

df_dropped_rows = df.dropna(axis=0)
print(“\n删除含有缺失值的行后:”)
print(df_dropped_rows)

axis=1 删除含有缺失值的列

df_dropped_cols = df.dropna(axis=1)
print(“\n删除含有缺失值的列后:”)
print(df_dropped_cols)

.dropna() 也有其他参数,例如 how=’all’ (只删除所有值都是缺失值的行/列)

thresh=n (删除非缺失值数量少于 n 的行/列)

填充缺失值

用特定值填充

df_filled_value = df.fillna(0) # 用 0 填充所有缺失值
print(“\n用 0 填充缺失值后:”)
print(df_filled_value)

用列的均值填充 (常用方法)

mean_score = df[‘score’].mean()
df_filled_mean = df[‘score’].fillna(mean_score)
print(“\n用 score 列均值填充缺失值后的 score 列:”)
print(df_filled_mean)

使用前一个非缺失值填充 (向前填充)

df_filled_ffill = df.fillna(method=’ffill’)
print(“\n使用 ffill 填充缺失值后:”)
print(df_filled_ffill)

使用后一个非缺失值填充 (向后填充)

df_filled_bfill = df.fillna(method=’bfill’)
print(“\n使用 bfill 填充缺失值后:”)
print(df_filled_bfill)
“`

数据类型转换 (.astype())

有时需要改变列的数据类型,例如将字符串转换为数字,或者将浮点数转换为整数。

“`python
print(“\n— 数据类型转换 —“)

查看当前数据类型

print(“\n原始数据类型:”)
print(df.dtypes)

将 ‘age’ 列转换为 float

df[‘age’] = df[‘age’].astype(float)
print(“\n将 ‘age’ 转换为 float 后:”)
print(df.dtypes)

如果列中有缺失值 (NaN),转换为整数会失败,需要先处理缺失值

例如,先填充再转换

df[‘score’] = df[‘score’].fillna(0).astype(int) # 假设填充后可以转为整数

“`

8. 数据排序

你可以按值或按索引对 DataFrame 进行排序。

“`python
print(“\n— 数据排序 —“)

按某一列的值排序 (默认升序)

df_sorted_age = df.sort_values(by=’age’)
print(“\n按 age 升序排序:”)
print(df_sorted_age)

按某一列的值降序排序

df_sorted_age_desc = df.sort_values(by=’age’, ascending=False)
print(“\n按 age 降序排序:”)
print(df_sorted_age_desc)

按多列值排序 (先按第一列排序,再按第二列排序…)

df_sorted_multi = df.sort_values(by=[‘city’, ‘age’])
print(“\n按 city 然后按 age 排序:”)
print(df_sorted_multi)

按索引排序 (默认升序)

df_reversed_index = df.iloc[::-1] # 创建一个索引倒序的 DataFrame
df_sorted_index = df_reversed_index.sort_index()
print(“\n按索引排序:”)
print(df_sorted_index)

按索引降序排序

df_sorted_index_desc = df.sort_index(ascending=False)
print(“\n按索引降序排序:”)
print(df_sorted_index_desc)
“`

9. 数据分组与聚合 (.groupby())

groupby() 是 Pandas 中用于执行“分拆 (Split) – 应用 (Apply) – 组合 (Combine)”操作的核心函数。它允许你根据某一列或多列的值将数据分成组,然后对每个组独立地应用一个函数(如求和、平均值、计数等),最后将结果组合起来。

“`python
print(“\n— 数据分组与聚合 (.groupby()) —“)

按 ‘city’ 列分组,并计算每个城市的平均年龄

print(“\n按 city 分组计算平均年龄:”)
print(df.groupby(‘city’)[‘age’].mean()) # 选择 ‘age’ 列并计算平均值

按 ‘city’ 列分组,并对 ‘age’ 和 ‘score’ 两列计算平均值

print(“\n按 city 分组计算 age 和 score 的平均值:”)
print(df.groupby(‘city’)[[‘age’, ‘score’]].mean())

按 ‘city’ 分组,并计算每组的大小 (即每个城市有多少人)

print(“\n按 city 分组计算数量:”)
print(df.groupby(‘city’).size()) # 或者 .count(),但 size 更通用,包括缺失值

对分组后的对象应用多个聚合函数

print(“\n按 city 分组,计算 age 的总和、平均值和数量:”)
print(df.groupby(‘city’)[‘age’].agg([‘sum’, ‘mean’, ‘count’]))

对不同列应用不同的聚合函数

print(“\n按 city 分组,age 计算平均值,score 计算总和:”)
print(df.groupby(‘city’).agg({‘age’: ‘mean’, ‘score’: ‘sum’}))
“`

groupby() 是进行分组分析、计算汇总统计量的强大工具。

10. 数据合并 (.merge())

在实际应用中,数据通常分布在多个表(DataFrame)中。pd.merge() 函数允许你根据一个或多个键将不同的 DataFrame 合并起来,类似于 SQL 中的 JOIN 操作。

“`python
print(“\n— 数据合并 (.merge()) —“)

创建两个示例 DataFrame

df_info = pd.DataFrame({
‘id’: [1, 2, 3, 4, 5],
‘name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eva’]
})

df_sales = pd.DataFrame({
‘id’: [1, 2, 3, 6, 7], # 注意这里有一些 id 不在 df_info 中
‘sales’: [100, 150, 200, 50, 120]
})

print(“df_info:”)
print(df_info)
print(“\ndf_sales:”)
print(df_sales)

内连接 (inner join): 只保留两个 DataFrame 中都有的 id

df_merged_inner = pd.merge(df_info, df_sales, on=’id’, how=’inner’)
print(“\n内连接 (inner merge on ‘id’):”)
print(df_merged_inner)

左连接 (left join): 保留左边 DataFrame (df_info) 的所有 id,右边没有的用 NaN 填充

df_merged_left = pd.merge(df_info, df_sales, on=’id’, how=’left’)
print(“\n左连接 (left merge on ‘id’):”)
print(df_merged_left)

右连接 (right join): 保留右边 DataFrame (df_sales) 的所有 id,左边没有的用 NaN 填充

df_merged_right = pd.merge(df_info, df_sales, on=’id’, how=’right’)
print(“\n右连接 (right merge on ‘id’):”)
print(df_merged_right)

外连接 (outer join): 保留所有 id,没有对应值的用 NaN 填充

df_merged_outer = pd.merge(df_info, df_sales, on=’id’, how=’outer’)
print(“\n外连接 (outer merge on ‘id’):”)
print(df_merged_outer)

如果连接键在两个 DataFrame 中名字不同,可以使用 left_on 和 right_on

如果需要基于索引合并,可以使用 left_index=True, right_index=True

“`

pd.merge() 是整合来自不同来源数据的关键操作。

11. 数据输出

将处理和分析后的数据保存到文件也非常重要。

“`python
print(“\n— 数据输出 —“)

将 DataFrame 保存到 CSV 文件

index=False 表示不将 DataFrame 的索引写入文件

try:
df.to_csv(‘output_data.csv’, index=False)
print(“\nDataFrame 已保存到 output_data.csv”)
except Exception as e:
print(f”\n保存 CSV 失败:{e}”)

将 DataFrame 保存到 Excel 文件

需要安装 openpyxl 或 xlrd

try:
df.to_excel(‘output_data.xlsx’, index=False)
print(“DataFrame 已保存到 output_data.xlsx”)
except ImportError:
print(“警告:未安装 openpyxl 或 xlrd,无法保存 Excel 文件。”)
except Exception as e:
print(f”保存 Excel 失败:{e}”)

还有 to_json(), to_sql(), to_html() 等方法

“`

12. 总结与展望

恭喜你!你已经完成了 Pandas 入门的关键学习。我们从 Pandas 的基本概念、核心数据结构 Series 和 DataFrame 入手,学习了如何创建数据、查看数据概览、进行强大的数据选择和过滤、执行基本的数据清洗(处理缺失值、类型转换)、数据排序、分组聚合以及数据合并。

Pandas 的功能远不止于此。随着你对 Pandas 的深入使用,你还会接触到:

  • 时间序列数据处理
  • 窗口函数 (rolling, expanding)
  • 数据透视表 (pivot_table)
  • Categorical 数据类型
  • 更高级的 Apply 操作
  • 结合 Matplotlib/Seaborn 进行数据可视化

Pandas 是一个庞大而灵活的库,掌握它需要持续的练习和实践。尝试将你遇到的实际数据问题用 Pandas 来解决,多查阅官方文档,你会发现 Pandas 能极大地提高你的数据处理效率。

希望这篇详细的入门指南为你打下了坚实的基础。现在,就开始你的 Pandas 数据分析之旅吧!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部