Python Pandas 教程:快速掌握数据清洗与分析 – wiki基地


Python Pandas 教程:快速掌握数据清洗与分析

在当今数据驱动的世界中,数据已成为各行各业的宝贵资产。然而,原始数据往往是杂乱无章、不完整或格式不一致的。为了从数据中提取有价值的见解,我们首先需要对其进行清洗、转换和分析。Python 的 Pandas 库正是为此而生,它提供了一套强大而灵活的工具,让数据处理变得高效而愉快。

本教程将带你快速掌握 Pandas 的核心概念和常用功能,助你成为数据清洗与分析的高手。

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

Pandas 是基于 NumPy 构建的 Python 数据分析库,提供了高性能、易于使用的数据结构和数据分析工具。它的核心优势在于:

  • 强大的数据结构:主要提供 Series (一维带标签数组) 和 DataFrame (二维带标签表格数据结构)。
  • 灵活的数据导入/导出:支持从多种格式(CSV, Excel, SQL 数据库, JSON, HDF5 等)读取和写入数据。
  • 高效的数据操作:提供丰富的数据筛选、切片、合并、重塑、分组、聚合功能。
  • 缺失数据处理:内置处理缺失值的简便方法。
  • 时间序列功能:强大的时间序列处理能力。

简而言之,Pandas 是数据科学家和分析师进行数据预处理、探索性数据分析(EDA)和特征工程的首选工具。

2. 安装 Pandas

如果你还没有安装 Pandas,可以通过 pip 包管理器轻松安装:

bash
pip install pandas openpyxl # openpyxl 用于读取和写入 Excel 文件

安装完成后,你可以在 Python 脚本中导入它:

python
import pandas as pd
import numpy as np # 通常与 Pandas 一起使用

3. Pandas 核心数据结构

Pandas 提供了两种主要的数据结构:SeriesDataFrame

3.1 Series (系列)

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

“`python

从列表中创建 Series

s = pd.Series([1, 3, 5, np.nan, 6, 8])
print(“Series from list:\n”, s)

从字典创建 Series

data = {‘a’: 10, ‘b’: 20, ‘c’: 30}
s_dict = pd.Series(data)
print(“\nSeries from dictionary:\n”, s_dict)
“`

3.2 DataFrame (数据框)

DataFrame 是 Pandas 最常用的数据结构,可以看作是一个带行和列标签的二维表格。它由多个 Series 组成,共享同一个索引。

“`python

从字典创建 DataFrame

data = {
‘姓名’: [‘张三’, ‘李四’, ‘王五’, ‘赵六’],
‘年龄’: [25, 30, 22, 28],
‘城市’: [‘北京’, ‘上海’, ‘广州’, ‘深圳’]
}
df = pd.DataFrame(data)
print(“DataFrame from dictionary:\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(“\nDataFrame from NumPy array:\n”, df2)
“`

4. 导入与导出数据

Pandas 支持多种数据格式的读写。

4.1 读取数据

“`python

读取 CSV 文件

df_csv = pd.read_csv(‘data.csv’)

读取 Excel 文件

df_excel = pd.read_excel(‘data.xlsx’, sheet_name=’Sheet1′)

读取 JSON 文件

df_json = pd.read_json(‘data.json’)

示例:创建一个CSV文件用于演示

df.to_csv(‘sample_data.csv’, index=False) # 保存DataFrame到CSV
print(“\n’sample_data.csv’ created.”)
df_sample = pd.read_csv(‘sample_data.csv’)
print(“\nRead from CSV:\n”, df_sample)
“`

4.2 导出数据

“`python

导出为 CSV 文件

df.to_csv(‘output.csv’, index=False) # index=False 不写入行索引

导出为 Excel 文件

df.to_excel(‘output.xlsx’, sheet_name=’Sheet1′, index=False)

导出为 JSON 文件

df.to_json(‘output.json’, orient=’records’)

“`

5. 数据初步探索 (EDA)

在进行数据清洗和分析之前,了解数据的基本情况至关重要。

“`python

假设我们正在处理 df_sample

print(“\n— Data Exploration —“)
print(“First 5 rows:\n”, df_sample.head()) # 查看前5行
print(“\nLast 3 rows:\n”, df_sample.tail(3)) # 查看后3行

print(“\nDataFrame Info (数据概览):\n”)
df_sample.info() # 获取 DataFrame 的摘要信息,包括数据类型、非空值数量

print(“\nDescriptive Statistics (描述性统计):\n”, df_sample.describe()) # 对数值列进行描述性统计

print(“\nDataFrame Shape (行数, 列数):\n”, df_sample.shape) # 获取 DataFrame 的维度 (行数, 列数)

print(“\nColumn Names (列名):\n”, df_sample.columns) # 获取所有列名

print(“\nData Types (数据类型):\n”, df_sample.dtypes) # 获取每列的数据类型
“`

6. 数据清洗

数据清洗是数据分析过程中最耗时但至关重要的一步。

6.1 处理缺失值

缺失值(NaNNone)是常见的数据问题。

“`python

创建一个带缺失值的 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— Handling Missing Values —“)
print(“Original DataFrame with missing values:\n”, df_missing)

检查缺失值

print(“\nCheck for null values:\n”, df_missing.isnull())
print(“\nTotal null values per column:\n”, df_missing.isnull().sum())

删除含有缺失值的行

df_dropna_row = df_missing.dropna()
print(“\nDataFrame after dropping rows with any NaN:\n”, df_dropna_row)

删除含有所有缺失值的行 (how=’all’)

df_dropna_all = df_missing.dropna(how=’all’)
print(“\nDataFrame after dropping rows with all NaN (if any):\n”, df_dropna_all)

填充缺失值

1. 用固定值填充

df_fill_zero = df_missing.fillna(0)
print(“\nDataFrame after filling NaN with 0:\n”, df_fill_zero)

2. 用列的均值填充

df_fill_mean = df_missing.fillna(df_missing[‘A’].mean())
print(“\nDataFrame after filling NaN in ‘A’ with its mean (and others with overall mean if not specified):\n”, df_fill_mean)

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

df_ffill = df_missing.fillna(method=’ffill’)
print(“\nDataFrame after forward fill (ffill):\n”, df_ffill)

4. 使用后一个有效值填充 (backward fill)

df_bfill = df_missing.fillna(method=’bfill’)
print(“\nDataFrame after backward fill (bfill):\n”, df_bfill)
“`

6.2 删除重复值

重复行可能会影响分析结果,需要进行处理。

“`python
df_duplicates = pd.DataFrame({
‘A’: [1, 2, 2, 3, 1],
‘B’: [‘x’, ‘y’, ‘y’, ‘z’, ‘x’]
})
print(“\n— Removing Duplicates —“)
print(“Original DataFrame with duplicates:\n”, df_duplicates)

查找重复行

print(“\nCheck for duplicated rows:\n”, df_duplicates.duplicated())

删除重复行 (默认保留第一个)

df_no_duplicates = df_duplicates.drop_duplicates()
print(“\nDataFrame after dropping duplicates:\n”, df_no_duplicates)

删除重复行,保留最后一个

df_no_duplicates_last = df_duplicates.drop_duplicates(keep=’last’)
print(“\nDataFrame after dropping duplicates (keep last):\n”, df_no_duplicates_last)

基于特定列删除重复项

df_no_duplicates_A = df_duplicates.drop_duplicates(subset=[‘A’])
print(“\nDataFrame after dropping duplicates based on ‘A’ column:\n”, df_no_duplicates_A)
“`

6.3 更改数据类型

有时数据导入后类型不正确,需要手动转换。

“`python
df_types = pd.DataFrame({
‘A’: [‘1’, ‘2’, ‘3’],
‘B’: [‘4.5’, ‘5.5’, ‘6.5’],
‘C’: [‘True’, ‘False’, ‘True’]
})
print(“\n— Correcting Data Types —“)
print(“Original DataFrame data types:\n”, df_types.dtypes)

将 ‘A’ 列转换为整数

df_types[‘A’] = df_types[‘A’].astype(int)

将 ‘B’ 列转换为浮点数

df_types[‘B’] = df_types[‘B’].astype(float)

将 ‘C’ 列转换为布尔型

df_types[‘C’] = df_types[‘C’].astype(bool)

print(“\nDataFrame data types after conversion:\n”, df_types.dtypes)
“`

6.4 重命名列名

清晰的列名有助于理解数据。

“`python
print(“\n— Renaming Columns —“)
print(“Original df_sample columns:\n”, df_sample.columns)

重命名单个或多个列

df_renamed = df_sample.rename(columns={‘姓名’: ‘Name’, ‘年龄’: ‘Age’})
print(“\nDataFrame after renaming columns:\n”, df_renamed)
“`

7. 数据选择与过滤

从 DataFrame 中提取所需数据是日常操作。

7.1 选择列

“`python
print(“\n— Data Selection and Filtering —“)
print(“Original df_sample:\n”, df_sample)

选择单个列 (Series)

name_column = df_sample[‘姓名’]
print(“\nSelecting ‘姓名’ column:\n”, name_column)

选择多个列 (DataFrame)

name_city_columns = df_sample[[‘姓名’, ‘城市’]]
print(“\nSelecting ‘姓名’ and ‘城市’ columns:\n”, name_city_columns)
“`

7.2 选择行 (基于索引和标签)

  • loc:基于标签(行索引和列名)选择。
  • iloc:基于整数位置(行号和列号)选择。

“`python

使用 loc 选择行

选择第一行 (索引为0的行)

first_row_loc = df_sample.loc[0]
print(“\nSelecting first row using loc (index 0):\n”, first_row_loc)

选择指定索引的多行

multiple_rows_loc = df_sample.loc[[0, 2]]
print(“\nSelecting rows with index 0 and 2 using loc:\n”, multiple_rows_loc)

使用 iloc 选择行

选择第一行 (位置为0的行)

first_row_iloc = df_sample.iloc[0]
print(“\nSelecting first row using iloc (position 0):\n”, first_row_iloc)

选择指定位置的多行

multiple_rows_iloc = df_sample.iloc[[0, 2]]
print(“\nSelecting rows with position 0 and 2 using iloc:\n”, multiple_rows_iloc)

结合行和列选择

选择第一行的 ‘姓名’ 列

value_loc = df_sample.loc[0, ‘姓名’]
print(“\nSelecting ‘姓名’ from first row using loc:\n”, value_loc)

选择前两行的 ‘姓名’ 和 ‘年龄’ 列

subset_loc = df_sample.loc[0:1, [‘姓名’, ‘年龄’]]
print(“\nSelecting first two rows, ‘姓名’ and ‘年龄’ using loc:\n”, subset_loc)

选择所有行的第一列和第三列

subset_iloc = df_sample.iloc[:, [0, 2]]
print(“\nSelecting all rows, first and third column using iloc:\n”, subset_iloc)
“`

7.3 条件筛选

使用布尔条件筛选数据。

“`python

筛选年龄大于25的行

age_filter = df_sample[df_sample[‘年龄’] > 25]
print(“\nRows where Age > 25:\n”, age_filter)

筛选城市是 ‘北京’ 且年龄小于 30 的行

complex_filter = df_sample[(df_sample[‘城市’] == ‘北京’) & (df_sample[‘年龄’] < 30)]
print(“\nRows where City is ‘北京’ and Age < 30:\n”, complex_filter)

筛选城市在列表中的行

city_list_filter = df_sample[df_sample[‘城市’].isin([‘北京’, ‘深圳’])]
print(“\nRows where City is ‘北京’ or ‘深圳’:\n”, city_list_filter)
“`

8. 数据操作与转换

Pandas 提供了丰富的数据操作功能。

8.1 应用函数 (apply(), map())

  • apply():用于在 DataFrame 的行或列上应用函数。
  • map():用于 Series 上的值到值的映射。

“`python
print(“\n— Data Manipulation —“)

假设我们想给每个人的年龄加一岁

df_manipulate = df_sample.copy()
df_manipulate[‘年龄_新’] = df_manipulate[‘年龄’].apply(lambda x: x + 1)
print(“\nAdding 1 to Age using apply:\n”, df_manipulate)

创建一个映射字典

city_map = {‘北京’: ‘Beijing’, ‘上海’: ‘Shanghai’, ‘广州’: ‘Guangzhou’, ‘深圳’: ‘Shenzhen’}
df_manipulate[‘城市_英文’] = df_manipulate[‘城市’].map(city_map)
print(“\nMapping Chinese cities to English using map:\n”, df_manipulate)
“`

8.2 数据排序 (sort_values())

“`python

按年龄升序排列

df_sorted_age = df_sample.sort_values(by=’年龄’)
print(“\nDataFrame sorted by Age (ascending):\n”, df_sorted_age)

按年龄降序排列

df_sorted_age_desc = df_sample.sort_values(by=’年龄’, ascending=False)
print(“\nDataFrame sorted by Age (descending):\n”, df_sorted_age_desc)

按多个列排序 (先按城市,再按年龄)

df_sorted_multi = df_sample.sort_values(by=[‘城市’, ‘年龄’])
print(“\nDataFrame sorted by City then Age:\n”, df_sorted_multi)
“`

8.3 数据分组与聚合 (groupby())

groupby() 是 Pandas 中非常强大的功能,用于根据一个或多个列的值将数据分成组,然后对每个组进行独立的计算。

“`python
data_group = {
‘部门’: [‘销售’, ‘市场’, ‘销售’, ‘技术’, ‘市场’, ‘技术’],
‘员工’: [‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’],
‘薪资’: [5000, 6000, 5500, 7000, 6200, 7500],
‘绩效’: [80, 90, 85, 95, 88, 92]
}
df_group = pd.DataFrame(data_group)
print(“\n— Grouping Data (groupby) —“)
print(“Original DataFrame for grouping:\n”, df_group)

按部门分组并计算平均薪资

avg_salary_by_dept = df_group.groupby(‘部门’)[‘薪资’].mean()
print(“\nAverage Salary by Department:\n”, avg_salary_by_dept)

按部门分组并计算多个聚合统计量

dept_summary = df_group.groupby(‘部门’).agg({
‘薪资’: [‘mean’, ‘min’, ‘max’],
‘绩效’: ‘mean’
})
print(“\nDepartment Summary (mean, min, max salary; mean performance):\n”, dept_summary)
“`

8.4 合并与连接 (merge(), concat())

  • concat():按轴(行或列)连接 DataFrame。
  • merge():通过一个或多个键连接 DataFrame,类似于 SQL JOIN。

“`python
df1 = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K2’, ‘K3’], ‘A’: [‘A0’, ‘A1’, ‘A2’, ‘A3’]})
df2 = pd.DataFrame({‘key’: [‘K0’, ‘K1’, ‘K4’, ‘K5’], ‘B’: [‘B0’, ‘B1’, ‘B4’, ‘B5’]})
df3 = pd.DataFrame({‘A’: [‘A4’, ‘A5’], ‘B’: [‘B4’, ‘B5’]})

print(“\n— Merging and Concatenating DataFrames —“)
print(“df1:\n”, df1)
print(“df2:\n”, df2)
print(“df3:\n”, df3)

1. concat (按行连接)

df_concat_rows = pd.concat([df1, df3], ignore_index=True)
print(“\nConcatenated df1 and df3 (rows):\n”, df_concat_rows)

2. concat (按列连接)

df_concat_cols = pd.concat([df1, df2], axis=1) # 注意这里如果没有共同的索引,可能会有NaN
print(“\nConcatenated df1 and df2 (columns):\n”, df_concat_cols)

3. merge (内连接 – 默认)

df_merged_inner = pd.merge(df1, df2, on=’key’, how=’inner’)
print(“\nInner merge of df1 and df2 on ‘key’:\n”, df_merged_inner)

4. merge (左连接)

df_merged_left = pd.merge(df1, df2, on=’key’, how=’left’)
print(“\nLeft merge of df1 and df2 on ‘key’:\n”, df_merged_left)

5. merge (外连接)

df_merged_outer = pd.merge(df1, df2, on=’key’, how=’outer’)
print(“\nOuter merge of df1 and df2 on ‘key’:\n”, df_merged_outer)
“`

9. 简单数据分析与聚合

除了 groupby(),Pandas 还提供了一系列快捷的聚合函数。

“`python
print(“\n— Basic Data Analysis/Aggregation —“)

对数值列进行聚合操作

print(“\nMin Age:”, df_sample[‘年龄’].min())
print(“Max Age:”, df_sample[‘年龄’].max())
print(“Mean Age:”, df_sample[‘年龄’].mean())
print(“Sum of Ages:”, df_sample[‘年龄’].sum())
print(“Count of Ages:”, df_sample[‘年龄’].count())

计算城市列的唯一值及其计数

print(“\nValue counts for City:\n”, df_sample[‘城市’].value_counts())
“`

10. 结论与进阶

通过本教程,你已经掌握了 Python Pandas 进行数据清洗和分析的基础知识和常用操作。这包括:

  • 理解 SeriesDataFrame 两种核心数据结构。
  • 学会从不同文件格式导入和导出数据。
  • 掌握数据初步探索的方法。
  • 处理缺失值、重复值,以及数据类型转换和列重命名。
  • 灵活进行数据选择、过滤、排序。
  • 利用 apply()map() 进行数据转换。
  • 使用 groupby() 进行强大的数据分组与聚合。
  • 理解 concat()merge() 的数据连接操作。
  • 执行基础的统计聚合。

Pandas 的功能远不止于此,还有许多高级特性等待你去探索,例如:

  • 时间序列分析resample()shift() 等。
  • 窗口函数rolling()expanding() 等。
  • 透视表 (Pivot Tables)pivot_table()
  • 多级索引 (MultiIndex)
  • 结合 Matplotlib 和 Seaborn 进行数据可视化

持续实践是掌握 Pandas 的关键。尝试在真实数据集上运用这些技能,你将很快成为一名高效的数据分析师!


滚动至顶部