数据分析师必看:Python Pandas 教程
在当今数据驱动的世界中,数据分析师扮演着至关重要的角色。而 Python 凭借其强大的生态系统,已成为数据分析领域的首选语言之一。在这个生态系统中,Pandas 库无疑是数据分析师的“瑞士军刀”,它提供了高性能、易于使用的数据结构和数据分析工具,极大地简化了数据处理的流程。
本文将为数据分析师提供一个全面的 Pandas 教程,涵盖其核心概念、关键功能以及实际应用,助您在数据分析的道路上如虎添翼。
1. 什么是 Pandas?为什么选择它?
Pandas 是一个开源的 Python 库,用于数据操作和分析。它的核心是引入了两种新的数据结构:Series 和 DataFrame,它们能够轻松处理结构化数据。
为什么数据分析师需要 Pandas?
- 高效的数据结构:
DataFrame专为表格数据设计,能够存储和操作大量数据,其性能优化使其在处理大数据集时表现出色。 - 强大的数据处理能力: Pandas 提供了丰富的功能,包括数据清洗、转换、筛选、聚合、合并等,几乎涵盖了数据分析的每一个环节。
- 易于学习和使用: 语法直观,与 NumPy 紧密集成,并且拥有庞大的社区支持和详尽的文档。
- 兼容性强: 可以轻松读取和写入各种数据格式,如 CSV、Excel、SQL 数据库、JSON 等。
2. 安装 Pandas
如果您已经安装了 Anaconda(推荐),Pandas 已经预装。如果没有,可以通过 pip 进行安装:
bash
pip install pandas
通常,我们会将 Pandas 导入并约定使用 pd 作为别名:
python
import pandas as pd
3. Pandas 的核心数据结构
Pandas 主要围绕两种数据结构构建:Series 和 DataFrame。
3.1 Series (一维数据)
Series 是一种带标签的一维数组,可以存储任何数据类型(整数、浮点数、字符串、Python 对象等)。它由两部分组成:数据(values)和索引(index)。
创建 Series:
“`python
import pandas as pd
从列表创建
s = pd.Series([1, 3, 5, 7, 9])
print(s)
0 1
1 3
2 5
3 7
4 9
dtype: int64
从字典创建 (键作为索引)
data = {‘a’: 10, ‘b’: 20, ‘c’: 30}
s_dict = pd.Series(data)
print(s_dict)
a 10
b 20
c 30
dtype: int64
指定索引
s_indexed = pd.Series([10, 20, 30], index=[‘x’, ‘y’, ‘z’])
print(s_indexed)
x 10
y 20
z 30
dtype: int64
“`
3.2 DataFrame (二维数据)
DataFrame 是 Pandas 最常用的数据结构,可以看作是带有行和列标签的二维表格。它类似于 Excel 表格或 SQL 数据库中的表,每列可以包含不同的数据类型。
创建 DataFrame:
“`python
从字典创建
data = {
‘Name’: [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’],
‘Age’: [25, 30, 35, 40],
‘City’: [‘New York’, ‘London’, ‘Paris’, ‘Tokyo’]
}
df = pd.DataFrame(data)
print(df)
Name Age City
0 Alice 25 New York
1 Bob 30 London
2 Charlie 35 Paris
3 David 40 Tokyo
从列表的列表创建 (需要指定列名)
data_list = [[‘Alice’, 25, ‘New York’],
[‘Bob’, 30, ‘London’],
[‘Charlie’, 35, ‘Paris’]]
df_list = pd.DataFrame(data_list, columns=[‘Name’, ‘Age’, ‘City’])
print(df_list)
Name Age City
0 Alice 25 New York
1 Bob 30 London
2 Charlie 35 Paris
“`
4. 数据加载与保存
Pandas 提供了多种函数来加载和保存数据。
4.1 读取数据
-
CSV 文件:
pd.read_csv()python
df = pd.read_csv('data.csv') -
Excel 文件:
pd.read_excel()python
df = pd.read_excel('data.xlsx', sheet_name='Sheet1') -
SQL 数据库:
pd.read_sql_table()或pd.read_sql_query()python
from sqlalchemy import create_engine
engine = create_engine('sqlite:///my_database.db')
df = pd.read_sql_table('my_table', engine)
4.2 保存数据
-
CSV 文件:
df.to_csv()python
df.to_csv('output.csv', index=False) # index=False 不保存 DataFrame 的索引 -
Excel 文件:
df.to_excel()python
df.to_excel('output.xlsx', index=False, sheet_name='Results')
5. 数据初步探索与检查
加载数据后,第一步通常是进行初步探索,了解数据的结构和概况。
-
查看前几行/后几行:
df.head()/df.tail()python
print(df.head()) # 默认显示前5行
print(df.tail(3)) # 显示后3行 -
查看数据框信息:
df.info()提供每列的非空值数量、数据类型、内存使用情况等,有助于发现缺失值和数据类型问题。
python
df.info() -
查看描述性统计:
df.describe()针对数值型数据,计算均值、标准差、最小值、最大值、四分位数等;对非数值型数据,计算计数、唯一值、众数等。
python
print(df.describe())
print(df.describe(include='all')) # 包含所有类型列 -
查看数据框的形状:
df.shape返回一个元组
(行数, 列数)。python
print(df.shape) # (4, 3) -
查看列名:
df.columnspython
print(df.columns) # Index(['Name', 'Age', 'City'], dtype='object')
6. 数据选择与索引
Pandas 提供了多种强大的方式来选择数据,包括基于标签和基于位置的索引。
6.1 列选择
-
选择单列:
“`python
names = df[‘Name’] # 返回 Series
print(names)0 Alice
1 Bob
2 Charlie
3 David
Name: Name, dtype: object
“`
-
选择多列:
“`python
subset = df[[‘Name’, ‘Age’]] # 返回 DataFrame
print(subset)Name Age
0 Alice 25
1 Bob 30
2 Charlie 35
3 David 40
“`
6.2 行选择
-
使用
loc(基于标签索引)loc用于按标签选择行和列。“`python
选择单行
row_0 = df.loc[0]
print(row_0)Name Alice
Age 25
City New York
Name: 0, dtype: object
选择多行
rows_0_1 = df.loc[[0, 1]]
print(rows_0_1)Name Age City
0 Alice 25 New York
1 Bob 30 London
同时选择行和列
cell = df.loc[0, ‘Name’] # ‘Alice’
print(cell)
subset_loc = df.loc[0:2, [‘Name’, ‘City’]] # 包含索引2
print(subset_loc)Name City
0 Alice New York
1 Bob London
2 Charlie Paris
“`
-
使用
iloc(基于位置索引)iloc用于按整数位置选择行和列 (类似于 Python 列表切片,不包含结束位置)。“`python
选择单行
row_0_iloc = df.iloc[0]
print(row_0_iloc)选择多行
rows_0_1_iloc = df.iloc[0:2] # 选择第0和第1行
print(rows_0_1_iloc)Name Age City
0 Alice 25 New York
1 Bob 30 London
同时选择行和列
cell_iloc = df.iloc[0, 0] # ‘Alice’
print(cell_iloc)
subset_iloc = df.iloc[0:3, [0, 2]] # 第0、1、2行,第0、2列
print(subset_iloc)Name City
0 Alice New York
1 Bob London
2 Charlie Paris
“`
7. 数据清洗
数据清洗是数据分析中至关重要的一步,Pandas 提供了强大的工具来处理缺失值、重复值和数据类型不一致等问题。
7.1 处理缺失值
-
检查缺失值:
df.isnull()/df.isna()返回一个布尔型的 DataFrame,
True表示缺失。“`python
df_missing = pd.DataFrame({
‘A’: [1, 2, None, 4],
‘B’: [5, None, 7, 8],
‘C’: [9, 10, 11, 12]
})
print(df_missing.isnull())A B C
0 False False False
1 False True False
2 True False False
3 False False False
print(df_missing.isnull().sum()) # 计算每列的缺失值数量
A 1
B 1
C 0
dtype: int64
“`
-
删除缺失值:
df.dropna()“`python
删除含有任何缺失值的行
df_cleaned_rows = df_missing.dropna()
print(df_cleaned_rows)A B C
0 1.0 5.0 9
3 4.0 8.0 12
删除所有列都为缺失值的行
df_cleaned_all_na = df_missing.dropna(how=’all’)
删除含有缺失值的列
df_cleaned_cols = df_missing.dropna(axis=1)
print(df_cleaned_cols)C
0 9
1 10
2 11
3 12
“`
-
填充缺失值:
df.fillna()“`python
用固定值填充
df_filled_zero = df_missing.fillna(0)
print(df_filled_zero)A B C
0 1.0 5.0 9
1 2.0 0.0 10
2 0.0 7.0 11
3 4.0 8.0 12
用列的均值填充
df_filled_mean = df_missing.fillna(df_missing[‘A’].mean())
print(df_filled_mean)A B C
0 1.0 5.000000 9
1 2.0 2.333333 10
2 2.0 7.000000 11
3 4.0 8.000000 12
用前一个有效值填充 (forward fill)
df_ffill = df_missing.fillna(method=’ffill’)
print(df_ffill)A B C
0 1.0 5.0 9
1 2.0 5.0 10
2 2.0 7.0 11
3 4.0 8.0 12
用后一个有效值填充 (backward fill)
df_bfill = df_missing.fillna(method=’bfill’)
print(df_bfill)A B C
0 1.0 5.0 9
1 2.0 7.0 10
2 4.0 7.0 11
3 4.0 8.0 12
“`
7.2 处理重复值
-
检查重复值:
df.duplicated()返回一个布尔型的 Series,
True表示重复(除第一次出现外)。“`python
df_dups = pd.DataFrame({
‘A’: [1, 2, 1, 4],
‘B’: [5, 6, 5, 8]
})
print(df_dups.duplicated())0 False
1 False
2 True
3 False
dtype: bool
print(df_dups.duplicated().sum()) # 重复行的数量
1
“`
-
删除重复值:
df.drop_duplicates()“`python
删除重复行
df_no_dups = df_dups.drop_duplicates()
print(df_no_dups)A B
0 1 5
1 2 6
3 4 8
基于特定列删除重复值
df_dups_col = pd.DataFrame({
‘ID’: [1, 2, 1, 3],
‘Value’: [‘A’, ‘B’, ‘C’, ‘D’]
})
df_no_dups_id = df_dups_col.drop_duplicates(subset=[‘ID’], keep=’first’) # 保留第一个
print(df_no_dups_id)ID Value
0 1 A
1 2 B
3 3 D
“`
7.3 数据类型转换:df.astype()
在数据分析中,正确的数据类型至关重要。
“`python
df[‘Age’] = df[‘Age’].astype(float) # 将 ‘Age’ 列转换为浮点型
尝试转换为日期时间
df[‘Date_Str’] = [‘2023-01-01’, ‘2023-01-02’, ‘2023-01-03’, ‘2023-01-04’]
df[‘Date’] = pd.to_datetime(df[‘Date_Str’])
print(df.info())
“`
8. 数据操作
Pandas 提供了一系列强大的操作来转换和重塑数据。
8.1 筛选数据 (条件过滤)
使用布尔索引进行筛选。
“`python
筛选年龄大于30的人
old_people = df[df[‘Age’] > 30]
print(old_people)
Name Age City
2 Charlie 35 Paris
3 David 40 Tokyo
组合条件 (使用 & 和 |)
filtered_data = df[(df[‘Age’] > 30) & (df[‘City’] == ‘Tokyo’)]
print(filtered_data)
Name Age City
3 David 40 Tokyo
使用 .isin()
cities = [‘New York’, ‘Paris’]
filtered_cities = df[df[‘City’].isin(cities)]
print(filtered_cities)
Name Age City
0 Alice 25 New York
2 Charlie 35 Paris
“`
8.2 排序数据:df.sort_values()
“`python
按年龄升序排序
df_sorted_age = df.sort_values(by=’Age’)
print(df_sorted_age)
Name Age City
0 Alice 25 New York
1 Bob 30 London
2 Charlie 35 Paris
3 David 40 Tokyo
按年龄降序排序
df_sorted_age_desc = df.sort_values(by=’Age’, ascending=False)
print(df_sorted_age_desc)
按多列排序
df_sorted_multi = df.sort_values(by=[‘City’, ‘Age’], ascending=[True, False])
print(df_sorted_multi)
“`
8.3 分组聚合:df.groupby()
groupby() 是 Pandas 中最强大的功能之一,它允许您根据一个或多个列的值将数据分组,然后对每个组执行聚合操作(如求和、均值、计数等)。
“`python
data_agg = {
‘City’: [‘New York’, ‘London’, ‘New York’, ‘London’, ‘Paris’],
‘Gender’: [‘Male’, ‘Female’, ‘Male’, ‘Male’, ‘Female’],
‘Salary’: [50000, 60000, 70000, 55000, 62000]
}
df_agg = pd.DataFrame(data_agg)
print(df_agg)
计算每个城市的平均工资
avg_salary_by_city = df_agg.groupby(‘City’)[‘Salary’].mean()
print(avg_salary_by_city)
City
London 57500.0
New York 60000.0
Paris 62000.0
Name: Salary, dtype: float64
计算每个城市和性别的工资总和
total_salary_by_city_gender = df_agg.groupby([‘City’, ‘Gender’])[‘Salary’].sum()
print(total_salary_by_city_gender)
City Gender
London Female 60000
Male 55000
New York Male 120000
Paris Female 62000
Name: Salary, dtype: int64
同时应用多个聚合函数
agg_results = df_agg.groupby(‘City’)[‘Salary’].agg([‘mean’, ‘max’, ‘min’, ‘count’])
print(agg_results)
mean max min count
City
London 57500.0 60000 55000 2
New York 60000.0 70000 50000 2
Paris 62000.0 62000 62000 1
“`
8.4 合并与连接:pd.merge() / df.join() / pd.concat()
-
pd.merge()(类似 SQL 的 JOIN)用于将两个 DataFrame 基于一个或多个键进行合并。
“`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’]})内连接 (inner join, 默认)
merged_inner = pd.merge(df1, df2, on=’key’, how=’inner’)
print(merged_inner)key A B
0 K0 A0 B0
1 K1 A1 B1
左连接 (left join)
merged_left = pd.merge(df1, df2, on=’key’, how=’left’)
print(merged_left)key A B
0 K0 A0 B0
1 K1 A1 B1
2 K2 A2 NaN
3 K3 A3 NaN
“`
-
pd.concat()(堆叠 DataFrame)用于沿轴(行或列)连接多个 DataFrame。
“`python
df_concat1 = pd.DataFrame({‘A’: [1, 2], ‘B’: [3, 4]})
df_concat2 = pd.DataFrame({‘A’: [5, 6], ‘B’: [7, 8]})按行连接 (默认 axis=0)
concat_rows = pd.concat([df_concat1, df_concat2])
print(concat_rows)A B
0 1 3
1 2 4
0 5 7
1 6 8
按列连接 (axis=1)
concat_cols = pd.concat([df_concat1, df_concat2], axis=1)
print(concat_cols)A B A B
0 1 3 5 7
1 2 4 6 8
“`
9. 数据可视化 (简要提及)
Pandas 自身集成了 Matplotlib,可以直接从 DataFrame 绘制图表,方便快速可视化数据趋势和分布。
“`python
import matplotlib.pyplot as plt
绘制年龄分布的直方图
df[‘Age’].plot(kind=’hist’, bins=5, title=’Age Distribution’)
plt.show()
绘制城市和工资的散点图
df_agg.plot(kind=’scatter’, x=’City’, y=’Salary’, title=’City vs Salary’)
plt.show()
“`
对于更复杂或更美观的图表,通常会结合 Seaborn 库使用。
10. 结论
Pandas 是 Python 数据分析领域的基石,掌握它对于任何数据分析师来说都至关重要。本文为您介绍了 Pandas 的核心数据结构、数据加载与保存、初步探索、选择与索引、数据清洗以及数据操作等关键功能。
从现在开始,您已经具备了使用 Pandas 进行基础数据分析的能力。但这仅仅是冰山一角,Pandas 还有更多高级功能等待您去探索,例如时间序列分析、窗口函数等。持续学习和实践,您将能够利用 Pandas 揭示数据背后的价值,做出更明智的决策。祝您在数据分析的旅程中一切顺利!