Pandas库入门教程
引言
在上一节中,我们介绍了NumPy库的强大数据计算功能,但在处理带标签的数据时,NumPy显得有些力不从心。因此,今天我们来介绍一个基于NumPy发展而来的强大数据操作库——Pandas。Pandas不仅继承了NumPy的优点,还提供了更多高级的数据处理工具,特别是在数据分析方面表现出色。本文将带你深入了解Pandas库的核心功能和应用场景。
Pandas的特点
Pandas库的主要特点是它侧重于数据分析,提供了丰富的高级工具。其核心数据结构包括:
- 基于NumPy:继承了NumPy的高效计算能力。
- 侧重数据分析:提供了丰富的数据分析工具。
- 数据结构:包含两种主要对象:
Series
(一维)和DataFrame
(多维)。 - Series:一维带标签的数组
- DataFrame:多维带标签的数组
创建Pandas对象
Series对象
Series对象的创建非常简单,可以通过列表、字典或NumPy数组来创建。例如:
import pandas as pd
使用列表创建Series
s = pd.Series([1, 2, 3, 4])
使用字典创建Series
population_dict = {‘Beijing’: 2154, ‘Shanghai’: 2424}
s = pd.Series(population_dict)
使用NumPy数组创建Series
import numpy as np
arr = np.array([1, 2, 3, 4])
s = pd.Series(arr)
DataFrame对象
DataFrame对象可以由多个Series对象、字典列表或二维NumPy数组创建。例如:
# 使用多个Series对象创建DataFrame
population = pd.Series({'Beijing': 2154, 'Shanghai': 2424})
gdp = pd.Series({'Beijing': 30320, 'Shanghai': 32680})
df = pd.DataFrame({'Population': population, 'GDP': gdp})
使用字典列表创建DataFrame
data = [{‘A’: 1, ‘B’: 2}, {‘A’: 5, ‘B’: 10}]
df = pd.DataFrame(data)
DataFrame的基本属性和操作
属性
values:返回底层的NumPy数组
index:返回行标签
columns:返回列标签
shape:返回形状(行数,列数)
size:返回元素总数
dtypes:返回每列的数据类型
索引和切片
列索引
# 获取单列
df['Population']
获取多列
df[[‘Population’, ‘GDP’]]
行索引
绝对索引:使用loc方法
相对索引:使用iloc方法
# 绝对索引
df.loc['Beijing']
相对索引
df.iloc[0]
同时对行和列进行切片
df.loc['Beijing':'Shanghai', 'Population':'GDP']
布尔索引
df[df['Population'] > 2200]
数据修改
# 修改单个值
df.loc['Beijing', 'Population'] = 2200
修改整列
df[‘Population’] = [2200, 2500]
修改行标签或列标签
df.index = [‘BJ’, ‘SH’]
df.columns = [‘Pop’, ‘GDP’]
数据运算和统计分析
运算
Pandas继承了NumPy的通用函数,支持向量化运算、矩阵化运算和广播运算。
# 向量化运算
df + 5
矩阵化运算
df.T @ df
广播运算
df / df.iloc[0]
统计分析
Pandas提供了丰富的统计方法,如mean、max、min、std等。特别地,describe方法可以一次性获取多种统计信息。
python复制df.describe()
自定义处理
使用apply方法可以将自定义函数应用到DataFrame的每一列或每一行。
python复制def custom_function(x):
return x.max() - x.min()
df.apply(custom_function)
缺失值处理
Pandas提供了多种处理缺失值的方法:
发现缺失值:isnull、notnull
删除缺失值:dropna
填充缺失值:fillna
# 发现缺失值
df.isnull()
删除缺失值
df.dropna()
填充缺失值
df.fillna(0)
数据合并
Pandas支持多种数据合并方式,如垂直合并(concat)、水平合并(merge)等。
python复制# 垂直合并
df1 = pd.DataFrame({‘A’: [1, 2], ‘B’: [3, 4]})
df2 = pd.DataFrame({‘A’: [5, 6], ‘B’: [7, 8]})
pd.concat([df1, df2])
水平合并
df1 = pd.DataFrame({‘A’: [1, 2], ‘B’: [3, 4]})
df2 = pd.DataFrame({‘C’: [5, 6], ‘D’: [7, 8]})
pd.concat([df1, df2], axis=1)
对齐合并
df1 = pd.DataFrame({‘key’: [‘one’, ‘two’], ‘A’: [1, 2]})
df2 = pd.DataFrame({‘key’: [‘one’, ‘two’], ‘B’: [3, 4]})
pd.merge(df1, df2, on=‘key’)
分组和数据透视表
分组
使用groupby方法可以对数据进行分组,并对每组数据进行聚合操作。
# 分组并求和
df.groupby('Category').sum()
分组并求平均值
df.groupby(‘Category’).mean()
数据透视表
数据透视表可以更直观地展示分组数据。
# 创建数据透视表
pd.pivot_table(df, values='Survived', index=['Sex'], columns=['Pclass'], aggfunc=np.mean)
多级索引
多级索引用于处理多维数据。
# 创建多级索引的DataFrame
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
df = pd.DataFrame(np.random.randn(8, 4), index=arrays, columns=['A', 'B', 'C', 'D'])
访问多级索引数据
df.loc[‘bar’, ‘one’]
性能优化
对于大规模数据的复合代数计算,可以使用eval和query方法减少内存分配,提升性能。
# 使用eval方法
df.eval('A + B')
使用query方法
df.query(‘A > 0 & B < 0’)
单选题
-
Pandas库是基于哪个库而发展的?
- A. TensorFlow
- B. NumPy
- C. Matplotlib
- D. Scikit-learn
答案:B. NumPy
-
Pandas库中的一维带标签数组被称为?
- A. DataFrame
- B. Series
- C. Array
- D. List
答案:B. Series
-
Pandas库中的多维带标签数组被称为?
- A. Series
- B. DataFrame
- C. Array
- D. List
答案:B. DataFrame
-
在Pandas中,创建一个Series对象时,如果不显式指定标签,默认的标签是什么?
- A. 字符串序列
- B. 浮点数序列
- C. 整数序列
- D. 布尔序列
答案:C. 整数序列
-
Pandas中,
DataFrame
对象的行标签和列标签可以通过哪个属性访问?- A.
index
和columns
- B.
labels
和columns
- C.
index
和labels
- D.
rows
和columns
答案:A.index
和columns
- A.
-
在Pandas中,
DataFrame
对象的索引方式中,loc
和iloc
的区别是什么?- A.
loc
基于相对位置索引,iloc
基于标签索引 - B.
loc
基于标签索引,iloc
基于相对位置索引 - C.
loc
和iloc
都是基于标签索引 - D.
loc
和iloc
都是基于相对位置索引
答案:B.loc
基于标签索引,iloc
基于相对位置索引
- A.
-
在Pandas中,
DataFrame
对象的布尔索引指的是什么?- A. 使用布尔值(True/False)作为索引条件进行数据筛选
- B. 使用字符串作为索引条件进行数据筛选
- C. 使用整数作为索引条件进行数据筛选
- D. 使用浮点数作为索引条件进行数据筛选
答案:A. 使用布尔值(True/False)作为索引条件进行数据筛选
-
在Pandas中,
DataFrame
对象的describe()
方法主要用于做什么?- A. 显示数据的基本统计信息
- B. 显示数据的详细内容
- C. 显示数据的结构
- D. 显示数据的类型
答案:A. 显示数据的基本统计信息
-
在Pandas中,处理缺失值的主要方法有哪些?
- A.
isnull()
和notnull()
- B.
dropna()
和fillna()
- C.
mean()
和median()
- D.
sum()
和count()
答案:B.dropna()
和fillna()
- A.
-
在Pandas中,
groupby()
方法的作用是什么?- A. 对数据进行排序
- B. 对数据进行分组
- C. 对数据进行合并
- D. 对数据进行清洗
答案:B. 对数据进行分组
多选题
-
Pandas库中,
DataFrame
对象的创建方式有哪些?- A. 使用Series对象
- B. 使用字典
- C. 使用列表
- D. 使用NumPy数组
答案:A. 使用Series对象, B. 使用字典, C. 使用列表, D. 使用NumPy数组
-
在Pandas中,
DataFrame
对象的索引方式有哪些?- A.
loc
- B.
iloc
- C.
at
- D.
iat
答案:A.loc
, B.iloc
, C.at
, D.iat
- A.
-
在Pandas中,
DataFrame
对象的统计方法有哪些?- A.
count()
- B.
mean()
- C.
median()
- D.
std()
答案:A.count()
, B.mean()
, C.median()
, D.std()
- A.
-
在Pandas中,处理缺失值的方法有哪些?
- A.
isnull()
- B.
notnull()
- C.
dropna()
- D.
fillna()
答案:A.isnull()
, B.notnull()
, C.dropna()
, D.fillna()
- A.
-
在Pandas中,数据合并的方式有哪些?
- A.
concat
- B.
merge
- C.
join
- D.
append
答案:A.concat
, B.merge
, C.join
, D.append
- A.
判断题
-
Pandas库中,
Series
对象只能存储一维数据。
答案:正确 -
Pandas库中,
DataFrame
对象只能存储二维数据。
答案:正确 -
Pandas库中,
DataFrame
对象的loc
和iloc
索引方式互不兼容。
答案:错误 -
Pandas库中,
DataFrame
对象的describe()
方法可以显示数据的详细内容。
答案:错误 -
Pandas库中,
groupby()
方法可以对数据进行分组并进行聚合操作。
答案:正确
习题
题目一:Pandas DataFrame创建与操作
小问1:
题目要求:创建一个30×6的DataFrame数组元素,由70到100之间均匀分布的随机整数构成。行标签按照初三二班一号一直到初三二班30号的格式,列标签分别为语文,数学,英语,物理,化学,计算机各科的名称。
- 答案:
首先,我们来导入pandas库和numpy库。然后去构建它的一个行标签。也就是从初三二班一号一直到初三二班30号。然后我们去构造列标签,也就是语文,数学,英语,物理,化学,计算机。然后将行标签和列标签以及数据放到pandas的DataFrame。
小问2:
题目要求:输出该DataFrame的纯数据,行标签,列标签,形状,大小以及数据类型。
- 答案:
我们可以使用df.values
输出它的纯数据,使用df.index
查看行标签,使用df.columns
查看列标签,使用df.shape
查看形状,使用df.size
查看大小,使用df.dtypes
查看数据类型。
小问3:
题目要求:获取全班的数学成绩以及获取学号为零三零二零五同学的所有成绩。
- 答案:
数学成绩可以直接用df['数学']
获得;获取学号为零三零二零五的成绩可以使用df.loc['零三零二零五']
。
小问4:
题目要求:增加总成绩这样一个新列,并且建立按照总成绩降序排列的副本,然后通过切片来获取前十名同学的全部成绩。
- 答案:
增加总成绩列可以使用df['总成绩'] = df.sum(axis=1)
,建立降序排列的副本可以使用df_sorted = df.sort_values(by='总成绩', ascending=False).copy()
,获取前十名同学的全部成绩可以使用df_sorted.head(10)
。
小问5:
题目要求:创建一个新的DataFrame对象,行标签与上文的DataFrame对象一致,列标签为性别,数据为30个学生的随机性别(A/B),然后将两个DataFrame对象进行水平合并,获得新的DataFrame对象。
- 答案:
首先随机得到30个学生的性别,可以使用np.random.choice(['A', 'B'], size=30)
,然后通过上述的行标签和列标签构造一个DataFrame对象,最后使用pd.concat([df, gender_df], axis=1)
进行水平合并。
小问6:
题目要求:输出上文提到的DataFrame对象的信息和描述统计信息,并尝试定义自己的统计信息输出。
- 答案:
可以使用df.info()
输出信息,使用df.describe()
输出描述统计信息,自定义统计信息可以使用df['性别'].value_counts()
。
小问7:
题目要求:按照性别进行分组对比,计算男生女生所有科目以及总成绩的平均值。
- 答案:
可以使用df.groupby('性别').mean()
计算所有科目以及总成绩的平均值。
题目二:Titanic 数据集操作
小问1:
题目要求:从titanic数据集中删除没有年龄数据的记录,并保存为一个副本。
- 答案:
可以使用df.dropna(subset=['Age']).copy()
删除没有年龄数据的记录并保存为副本。
小问2:
题目要求:创建一个名为age的Series对象,其数据来源于数据集中年龄,并按照如下规则进行映射:将年龄除以10再乘以10,转成int类型,再转成string类型并加上’s’。
- 答案:
可以使用age_series = (df['Age'].dropna() // 10 * 10).astype(int).astype(str) + 's'
创建映射后的Series对象。
小问3:
题目要求:通过sex和age对titanic数据集进行分组,以获得不同性别、不同年龄乘客的幸存比例,分别使用group by函数和pivot table函数。
- 答案:
使用group by函数可以使用df.groupby(['Sex', 'Age'])['Survived'].mean()
;使用pivot table函数可以使用pd.pivot_table(df, values='Survived', index='Sex', columns='Age', aggfunc=np.mean)
。