Python Pandas 详解:从入门到实践 – wiki大全

我无法直接将文章写入文件,因为我没有 write_file 工具。但我可以把文章内容直接输出给你。

Python Pandas 详解:从入门到实践

Python Pandas 是一个强大的数据处理和分析库,为 Python 编程语言带来了高性能、易于使用的数据结构和数据分析工具。它已成为数据科学家、数据分析师以及任何需要处理结构化数据的 Python 开发者不可或缺的工具。

1. 什么是 Pandas?

Pandas 的核心是其两种主要的数据结构:SeriesDataFrame。它建立在 NumPy 库之上,提供了快速、灵活且富有表现力的数据结构,旨在使“关系型”或“标签化”数据的使用变得简单直观。它特别适用于处理表格数据(如 SQL 表或 Excel 表格)、有序和无序(非固定频率)时间序列数据、以及带有行和列标签的任意矩阵数据。

2. 为什么使用 Pandas?

  • 数据清洗与准备: Pandas 提供了丰富的函数来处理缺失数据、重复数据、格式不一致的数据等,极大地简化了数据清洗的过程。
  • 数据探索与分析: 轻松地进行数据筛选、排序、分组、聚合等操作,帮助用户快速洞察数据。
  • 数据加载与存储: 支持多种文件格式(如 CSV、Excel、SQL 数据库、JSON、HDF5 等)的数据读取和写入。
  • 高效性能: 底层使用 C 语言编写的优化代码,使得 Pandas 在处理大量数据时依然保持高效。

3. 安装与导入

要使用 Pandas,首先需要安装它。推荐使用 pipconda 进行安装:

bash
pip install pandas numpy

安装完成后,可以在 Python 代码中导入 Pandas:

python
import pandas as pd
import numpy as np

通常使用 pd 作为 Pandas 的别名,这是社区的约定俗成。

4. 核心数据结构

4.1 Series(序列)

Series 是一种一维带标签的数组,可以存储任何数据类型(整数、浮点数、字符串、Python 对象等)。它由两部分组成:数据(values)和索引(index)。

创建 Series:

“`python

从列表创建

s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(“从列表创建 Series:\n”, s)

从 NumPy 数组创建,指定索引

dates = pd.date_range(“20230101”, periods=6)
s2 = pd.Series([10, 20, 30, 40, 50, 60], index=dates)
print(“\n从数组创建 Series (带索引):\n”, s2)

从字典创建

data_dict = {‘a’: 10, ‘b’: 20, ‘c’: 30}
s3 = pd.Series(data_dict)
print(“\n从字典创建 Series:\n”, s3)
“`

Series 的基本操作:

python
print("\nSeries 的值:\n", s.values)
print("\nSeries 的索引:\n", s.index)
print("\n获取第一个元素:", s[0])
print("\n按标签获取元素:", s3['b'])
print("\nSeries 运算:\n", s * 2)

4.2 DataFrame(数据帧)

DataFrame 是 Pandas 中最常用的数据结构,它是一个二维的、大小可变、可能异构的表格数据结构,类似于电子表格或 SQL 表。它有行和列,每列可以是不同的数据类型。

创建 DataFrame:

“`python

从字典创建 DataFrame

data = {
‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’],
‘Age’: [25, 30, 35, 28],
‘City’: [‘New York’, ‘Paris’, ‘London’, ‘Berlin’]
}
df = pd.DataFrame(data)
print(“从字典创建 DataFrame:\n”, df)

从 NumPy 数组创建 DataFrame,指定索引和列名

dates = pd.date_range(“20230101”, periods=6)
df2 = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list(“ABCD”))
print(“\n从 NumPy 数组创建 DataFrame (带索引和列名):\n”, df2)
“`

DataFrame 的基本属性:

python
print("\nDataFrame 的形状 (行数, 列数):", df.shape)
print("\nDataFrame 的列名:", df.columns)
print("\nDataFrame 的索引:", df.index)
print("\nDataFrame 每列的数据类型:\n", df.dtypes)
print("\n查看 DataFrame 的前几行 (默认为5行):\n", df.head(2))
print("\n查看 DataFrame 的后几行 (默认为5行):\n", df.tail(1))
print("\nDataFrame 的统计描述:\n", df.describe())

访问 DataFrame 中的数据:

  • 选择列:
    python
    print("\n选择单列 'Name':\n", df['Name'])
    print("\n选择多列 ['Name', 'Age']:\n", df[['Name', 'Age']])
  • 选择行(使用 lociloc):

    • loc:基于标签(label)的索引。
    • iloc:基于整数位置(integer position)的索引。

    “`python

    使用 loc (通过行标签和列标签)

    print(“\n使用 loc 选择第一行:\n”, df.loc[0])
    print(“\n使用 loc 选择多行:\n”, df.loc[0:2, [‘Name’, ‘City’]]) # 0到2行(包含2),Name和City列

    使用 iloc (通过整数位置)

    print(“\n使用 iloc 选择第一行:\n”, df.iloc[0])
    print(“\n使用 iloc 选择多行:\n”, df.iloc[0:3, [0, 2]]) # 0到2行(不包含3),第0和第2列
    “`

5. 数据加载与保存

Pandas 提供了方便的函数来读取和写入各种数据格式。

“`python

创建一个示例 DataFrame 用于保存

data_to_save = {
‘Product’: [‘Apple’, ‘Banana’, ‘Orange’],
‘Price’: [1.5, 0.75, 1.2],
‘Quantity’: [100, 200, 150]
}
df_save = pd.DataFrame(data_to_save)

保存到 CSV 文件

df_save.to_csv(‘products.csv’, index=False) # index=False 表示不保存行索引

print(“\n数据已保存到 products.csv (示例,实际未写入文件)”)

从 CSV 文件读取

df_loaded = pd.read_csv(‘products.csv’)

print(“\n从 products.csv 读取数据:\n”, df_loaded)

保存到 Excel 文件 (需要安装 openpyxl 或 xlwt/xlrd)

pip install openpyxl

df_save.to_excel(‘products.xlsx’, index=False)

print(“\n数据已保存到 products.xlsx (示例,实际未写入文件)”)

从 Excel 文件读取

df_excel_loaded = pd.read_excel(‘products.xlsx’)

print(“\n从 products.xlsx 读取数据:\n”, df_excel_loaded)

“`

6. 数据清洗与预处理

6.1 处理缺失数据

缺失数据通常表示为 NaN (Not a Number)。

“`python
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)

检测缺失值

print(“\n检测缺失值:\n”, df_missing.isnull())
print(“\n每列的缺失值数量:\n”, df_missing.isnull().sum())

删除含有缺失值的行

df_dropped_rows = df_missing.dropna()
print(“\n删除含有缺失值的行:\n”, df_dropped_rows)

删除所有列均为缺失值的行

df_dropped_all_nan = df_missing.dropna(how=’all’)

填充缺失值

df_filled_zero = df_missing.fillna(0)
print(“\n缺失值填充为 0:\n”, df_filled_zero)

使用前一个有效值填充 (forward fill)

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

使用列的平均值填充

df_filled_mean = df_missing.fillna(df_missing.mean())
print(“\n缺失值使用列平均值填充:\n”, df_filled_mean)
“`

6.2 更改数据类型

“`python
df_types = pd.DataFrame({‘col1’: [‘1’, ‘2’, ‘3’], ‘col2’: [‘A’, ‘B’, ‘C’]})
print(“\n原始 DataFrame 数据类型:\n”, df_types.dtypes)

将 ‘col1’ 从字符串更改为整数

df_types[‘col1’] = df_types[‘col1’].astype(int)
print(“\n更改数据类型后的 DataFrame:\n”, df_types.dtypes)
“`

6.3 删除重复项

“`python
df_duplicates = pd.DataFrame({
‘col1’: [1, 2, 1, 3],
‘col2’: [‘A’, ‘B’, ‘A’, ‘C’]
})
print(“\n原始 DataFrame (含重复项):\n”, df_duplicates)

删除所有列都重复的行

df_no_duplicates = df_duplicates.drop_duplicates()
print(“\n删除重复行后的 DataFrame:\n”, df_no_duplicates)

基于特定列删除重复项 (保留第一次出现)

df_no_duplicates_col1 = df_duplicates.drop_duplicates(subset=[‘col1’])
print(“\n基于 ‘col1’ 删除重复项:\n”, df_no_duplicates_col1)
“`

6.4 重命名列

“`python
df_rename = pd.DataFrame({‘old_name_A’: [1, 2], ‘old_name_B’: [3, 4]})
print(“\n原始 DataFrame (待重命名):\n”, df_rename)

df_renamed = df_rename.rename(columns={‘old_name_A’: ‘new_name_X’, ‘old_name_B’: ‘new_name_Y’})
print(“\n重命名列后的 DataFrame:\n”, df_renamed)
“`

7. 数据选择和过滤

7.1 条件筛选

“`python
df_filter = pd.DataFrame({
‘Category’: [‘A’, ‘B’, ‘A’, ‘C’, ‘B’],
‘Value’: [10, 20, 15, 25, 30]
})
print(“\n原始 DataFrame (用于筛选):\n”, df_filter)

选择 Category 为 ‘A’ 的行

filtered_df_A = df_filter[df_filter[‘Category’] == ‘A’]
print(“\nCategory 为 ‘A’ 的行:\n”, filtered_df_A)

组合条件

filtered_df_multi = df_filter[(df_filter[‘Category’] == ‘B’) & (df_filter[‘Value’] > 20)]
print(“\nCategory 为 ‘B’ 且 Value > 20 的行:\n”, filtered_df_multi)
“`

7.2 使用 query()

query() 方法提供了一种更简洁、更类似 SQL 的方式进行条件筛选。

python
queried_df = df_filter.query("Category == 'A' and Value > 12")
print("\n使用 query() 筛选:\n", queried_df)

7.3 使用 isin()

isin() 用于筛选列值是否在给定列表中。

python
filtered_isin = df_filter[df_filter['Category'].isin(['A', 'C'])]
print("\nCategory 在 ['A', 'C'] 中的行:\n", filtered_isin)

8. 数据分组与聚合

groupby() 是 Pandas 中最强大的功能之一,它允许你根据一个或多个列的值将数据拆分成组,然后对每个组独立地执行一些操作(聚合、转换、过滤)。

“`python
df_group = pd.DataFrame({
‘Region’: [‘East’, ‘West’, ‘East’, ‘West’, ‘East’],
‘Salesperson’: [‘Alice’, ‘Bob’, ‘Alice’, ‘Charlie’, ‘David’],
‘Sales’: [100, 150, 120, 200, 180]
})
print(“\n原始 DataFrame (用于分组):\n”, df_group)

按 ‘Region’ 分组并计算每个区域的总销售额

grouped_sales = df_group.groupby(‘Region’)[‘Sales’].sum()
print(“\n按 Region 分组的总销售额:\n”, grouped_sales)

按 ‘Region’ 分组并计算每个区域的平均销售额和销售数量

grouped_stats = df_group.groupby(‘Region’)[‘Sales’].agg([‘mean’, ‘count’])
print(“\n按 Region 分组的平均销售额和数量:\n”, grouped_stats)

按多个列分组

grouped_multi = df_group.groupby([‘Region’, ‘Salesperson’])[‘Sales’].sum()
print(“\n按 Region 和 Salesperson 分组的总销售额:\n”, grouped_multi)
“`

9. 合并、连接和连接 DataFrame

9.1 concat()(连接)

concat() 函数用于沿轴(默认是行)连接 Pandas 对象。

“`python
df1 = pd.DataFrame({‘A’: [‘A0’, ‘A1’], ‘B’: [‘B0’, ‘B1’]})
df2 = pd.DataFrame({‘A’: [‘A2’, ‘A3’], ‘B’: [‘B2’, ‘B3’]})

print(“\nDataFrame 1:\n”, df1)
print(“\nDataFrame 2:\n”, df2)

沿行方向连接 (默认)

result_rows = pd.concat([df1, df2])
print(“\n沿行方向连接:\n”, result_rows)

沿列方向连接

result_cols = pd.concat([df1, df2], axis=1)
print(“\n沿列方向连接:\n”, result_cols)
“`

9.2 merge()(合并)

merge() 函数用于通过一个或多个键将 DataFrame 中的行组合起来,类似于 SQL 中的 JOIN 操作。

“`python
df_left = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K2’, ‘K3’],
‘A’: [‘A0’, ‘A1’, ‘A2’, ‘A3’],
‘B’: [‘B0’, ‘B1’, ‘B2’, ‘B3’]})

df_right = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K4’, ‘K5’],
‘C’: [‘C0’, ‘C1’, ‘C2’, ‘C3’],
‘D’: [‘D0’, ‘D1’, ‘D2’, ‘D3’]})

print(“\nDataFrame Left:\n”, df_left)
print(“\nDataFrame Right:\n”, df_right)

内连接 (inner merge): 只保留两个 DataFrame 中 ‘key’ 列都存在的行

merged_inner = pd.merge(df_left, df_right, on=’key’, how=’inner’)
print(“\n内连接:\n”, merged_inner)

外连接 (outer merge): 保留所有行,缺失值用 NaN 填充

merged_outer = pd.merge(df_left, df_right, on=’key’, how=’outer’)
print(“\n外连接:\n”, merged_outer)

左连接 (left merge): 保留左边 DataFrame 的所有行

merged_left = pd.merge(df_left, df_right, on=’key’, how=’left’)
print(“\n左连接:\n”, merged_left)
“`

9.3 join()(连接)

join() 是一个方便的方法,用于连接具有相同或相似索引的 DataFrame,或者通过一个列作为键进行连接。它默认是左连接,并且通常在索引上进行操作。

“`python
df_join_left = pd.DataFrame({‘A’: [‘A0’, ‘A1’], ‘B’: [‘B0’, ‘B1’]}, index=[‘K0’, ‘K1’])
df_join_right = pd.DataFrame({‘C’: [‘C0’, ‘C1’], ‘D’: [‘D0’, ‘D1’]}, index=[‘K0’, ‘K2’])

print(“\nDataFrame Join Left:\n”, df_join_left)
print(“\nDataFrame Join Right:\n”, df_join_right)

默认左连接 (基于索引)

joined_df = df_join_left.join(df_join_right)
print(“\n默认左连接:\n”, joined_df)

内连接

joined_inner_df = df_join_left.join(df_join_right, how=’inner’)
print(“\n内连接:\n”, joined_inner_df)
“`

10. 时间序列分析(简介)

Pandas 在时间序列数据处理方面表现卓越。

“`python

创建日期范围作为索引

dates_ts = pd.date_range(‘2023-01-01′, periods=5, freq=’D’)
ts = pd.Series(np.random.randn(5), index=dates_ts)
print(“\n时间序列数据:\n”, ts)

将字符串转换为 datetime 对象

df_time = pd.DataFrame({‘date’: [‘2023-01-01’, ‘2023-01-02’, ‘2023-01-03’],
‘value’: [10, 20, 30]})
df_time[‘date’] = pd.to_datetime(df_time[‘date’])
print(“\n转换为 datetime 类型后的 DataFrame:\n”, df_time)
print(“日期列类型:”, df_time[‘date’].dtype)

设置日期列为索引

df_time = df_time.set_index(‘date’)
print(“\n日期列设置为索引:\n”, df_time)

重采样 (例如,按周求和)

resampled_weekly = ts.resample(‘W’).sum()

print(“\n按周重采样求和:\n”, resampled_weekly)

“`

11. 总结

Python Pandas 是一个功能强大且灵活的数据分析库。通过 SeriesDataFrame 这两种核心数据结构,它提供了从数据加载、清洗、预处理到数据分析、聚合、合并的完整工具集。无论是处理简单的表格数据还是复杂的时间序列数据,Pandas 都能显著提高数据处理的效率和代码的可读性。

希望这篇文章能帮助您从入门到实践,熟练掌握 Pandas 的基本功能。随着您对数据分析需求的深入,将会有更多高级功能等待您去探索,例如多级索引、窗口函数、类别数据处理等。持续练习和项目实践是掌握 Pandas 的最佳途径。

进一步学习资源:

  • Pandas 官方文档:https://pandas.pydata.org/docs/
  • Wes McKinney 的《Python for Data Analysis》一书。
  • 在线教程和数据科学平台(如 Kaggle、DataCamp 等)。
滚动至顶部