Numpy和Pandas的关系:就像先掌握算术才能学代数一样,NumPy就是数据分析的"算术基础",虽然可以直接用计算器(Pandas),但理解底层原理才能走得更远。
Pandas 核心数据机构是Series(数据系列)、DataFrame(数据窗/数据框),Series可以看做表中的一列,DataFrame则是整个表格,由多个列构成。除此之外还有一个特殊的Index类,为Series和DataFrame提供索引功能。
1 Series对象
1.1 创建 Series 对象
Series对象内部结构:一个ndarray用来保存数据,一个index用来保存索引。类似Numpy的一维数组,但是增加了“标签”,具有数据和索引。

- 通过列表和数组创建
data:数据index:索引name:名称
其中name的作用:
- 创建
DataFrame时自动变成列名 - 合并时作为对齐依据
- 导出csv时成为列名
import numpy as np
import pandas as pd
ser1 = pd.Series(data=np.arange(4), index=['春', '夏', '秋', '冬'], name='季节')
ser1
春 0
夏 1
秋 2
冬 3
Name: 季节, dtype: int32
- 通过字典创建
- 字典的键就是索引
- 字典的值就是数据
ser2 = pd.Series(data={'春': 1, '夏': 2, '秋': 3, '冬': 4})
ser2
春 1
夏 2
秋 3
冬 4
dtype: int64
1.2 Series 的运算
由于 Pandas 是基于 Numpy 开发的,所以很多性质和数组是一样的,比如矢量化运算和广播。
1.2.1 标量运算
ser1 += 10
ser1
春 10
夏 11
秋 12
冬 13
dtype: int32
1.2.2 矢量运算
ser1 += ser2
ser1
春 11
夏 13
秋 15
冬 17
dtype: int64
1.3 Series 的属性
dtype:返回Series对象的数据类型
ser1.dtype
dtype('int64')
size:返回Series对象中元素的个数
ser1.size
4
index:返回Series对象的索引Index对象
print('索引对象', ser1.index)
print('通过下标取出具体索引', ser1.index[0])
索引对象 Index(['春', '夏', '秋', '冬'], dtype='object')
通过下标取出具体索引 春
values:以ndarray的形式返回Series对象的值
print(ser1.values)
print('通过下标取出具体值', ser1.values[0])
[11 13 15 17]
通过下标取出具体值 11
1.4 Series 的方法
1.4.1 描述性统计
print('计数:', ser1.count())
print('求和:', ser1.sum())
print('均值:', ser1.mean())
print('中位数:', ser1.median())
print('最小值:', ser1.min())
print('最大值:', ser1.max())
print('标准差:', ser1.std())
print('方差:', ser1.var())
计数: 4
求和: 56
均值: 14.0
中位数: 14.0
最小值: 11
最大值: 17
标准差: 2.581988897471611
方差: 6.666666666666667
describe():获取描述性统计信息。
ser1.describe()
count 4.000000
mean 14.000000
std 2.581989
min 11.000000
25% 12.500000
50% 14.000000
75% 15.500000
max 17.000000
dtype: float64
describe()返回的是一个Series对象,所以可以通过索引访问。
print('平均值:', ser1.describe()['mean'])
print(f"最大值,最小值:\n{ser1.describe()[['max', 'min']]}")
平均值: 14.0
最大值,最小值:
max 17.0
min 11.0
dtype: float64
1.4.2 处理数据
isnull():空值判断notnull():非空值判断
ser2 = pd.Series(data=[10, 20, np.nan, 30, np.nan])
ser2.isnull()
0 False
1 False
2 True
3 False
4 True
dtype: bool
dropna():删除空值fillna():填充空值
处理数据的方法都有一个inplace参数,默认为False。
inplace=False:处理完成返回新的对象inplace=True:在原对象上进行处理
ser2.dropna()
0 10.0
1 20.0
3 30.0
dtype: float64
ser2.fillna(66, inplace=True)
ser2
0 10.0
1 20.0
2 66.0
3 30.0
4 66.0
dtype: float64
duplicated():检测重复数据drop_duplicates():删除重复数据unique:去除重复数据,返回一个数组
ser2.duplicated()
0 False
1 False
2 False
3 False
4 True
dtype: bool
ser2.drop_duplicates()
0 10.0
1 20.0
2 66.0
3 30.0
dtype: float64
ser2.unique()
array([10., 20., 66., 30.])
1.4.3 排序
sort_index():根据索引排序,默认升序sort_values():根据值排序,默认升序
使用ascending=False参数可以实现降序排列,排序结果返回一个新的 Series 对象,原对象不变。
ser3 = pd.Series(data=[30, 10, 20, 10, 50], index=['Bob', 'Alice', 'John', 'Eve', 'Jack'])
ser3.sort_index()
Alice 10
Bob 30
Eve 10
Jack 50
John 20
dtype: int64
ser3.sort_values(ascending=False, inplace=True)
ser3
Jack 50
Bob 30
John 20
Alice 10
Eve 10
dtype: int64
head(n):返回前 n 个元素,默认 n=5tail(n):返回后 n 个元素,默认 n=5
ser3.head(3)
Jack 50
Bob 30
John 20
dtype: int64
ser3.tail(2)
Alice 10
Eve 10
dtype: int64
1.4.4 绘制图表
Series对象可以直接绘制图表,默认绘制折线图,还可以绘制柱状图、饼图等,只需指定kind参数即可。默认会使用索引作为横坐标,值作为纵坐标。
import matplotlib.pyplot as plt
ser3.plot(kind='bar')

2 DataFrame 对象
DataFrame是一个二维的表格型数据结构,既有行索引,也有列索引,可以将其看作由多个Series按列组成的一个字典。是 Pandas 中最常用的数据结构,可以用来保存和处理异质的二维数据,每个列可以是不同的数据类型,这也是和 NumPy 数组的最大区别。
数据表格三要素贯穿 Pandas 数据分析的始终:
column:对应着列名,也就是列索引index:代表行索引value:则指代具体的数据值
2.1 创建 DataFrame 对象
2.1.1 通过二维数组/列表创建
data指定数据,columns指定列名,index指定行索引。
如果没有指定索引,则默认从 0 开始。如果没有指定列名,则默认从 0 开始。
score = np.random.randint(0, 101, size=(5, 3))
course = ['语文', '数学', '英语']
stu_id = ['1001', '1002', '1003', '1004', '1005']
df1 = pd.DataFrame(data=score, columns=course, index=stu_id)
df1
| 语文 | 数学 | 英语 | |
|---|---|---|---|
| 1001 | 1 | 83 | 92 |
| 1002 | 89 | 69 | 26 |
| 1003 | 90 | 12 | 74 |
| 1004 | 83 | 86 | 47 |
| 1005 | 73 | 93 | 71 |
2.1.2 通过字典创建
字典嵌套列表:按照列名进行创建 DataFrame 对象。
info1 = {
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [18, 19, 20, 21],
'性别': ['男', '女', '男', '女']
}
df2 = pd.DataFrame(data=info1)
df2
| 姓名 | 年龄 | 性别 | |
|---|---|---|---|
| 0 | 张三 | 18 | 男 |
| 1 | 李四 | 19 | 女 |
| 2 | 王五 | 20 | 男 |
| 3 | 赵六 | 21 | 女 |
列表嵌套列表:按照行进行创建 DataFrame 对象。
info2 = [
{'姓名': '张三', '年龄': 18, '性别': '男'},
{'姓名': '李四', '年龄': 19, '性别': '女'},
{'姓名': '王五', '年龄': 20, '性别': '男'},
{'姓名': '赵六', '年龄': 21, '性别': '女'}
]
df3 = pd.DataFrame(data=info2)
df3
| 姓名 | 年龄 | 性别 | |
|---|---|---|---|
| 0 | 张三 | 18 | 男 |
| 1 | 李四 | 19 | 女 |
| 2 | 王五 | 20 | 男 |
| 3 | 赵六 | 21 | 女 |
2.2 数据读取和存储
实际应用中,单独创建数据结构的情况较少,更多的是通过读取外部数据文件来创建数据结构。
2.2.1 读取 Excel
通过read_excel读取 Excel 文件,默认读取第一个 sheet,可以通过sheet_name参数指定读取的 sheet。
data1 = pd.read_excel('data/data1.xlsx')
data1
| 张三 | 88 | 100 | 90 | |
|---|---|---|---|---|
| 0 | 李四 | 82 | 65 | 52 |
| 1 | 王五 | 80 | 92 | 60 |
Pandas 默认会将第一行数据作为列名,如果想自定义列名,可以将header=None告诉Pandas数据中没有表头,然后通过names参数指定列名。
data1 = pd.read_excel('data/data1.xlsx', header=None, names=['姓名', '语文', '数学', '英语'])
data1
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
此外读取数据还有很多参数,比如:
index_col:指定哪一列作为行索引usecols:指定读取哪些列nrows:指定读取多少行dtype:指定列的数据类型
2.2.2 读取 CSV
通过read_csv函数可以读取 CSV 文件,默认使用UTF-8编码格式,如果是其他编码格式,可以通过encoding参数指定。
data2 = pd.read_csv('data/data2.csv')
data2
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
大多数CSV文件以逗号分隔,如果是其他字符分
隔,可以通过sep参数指定分隔符。
pd.read_csv('data/data2.csv', sep='\t')
在某些Python版本读取中文路径会报错,因为默认读取引擎是C语言,可以通过engine参数指定为Python引擎。
pd.read_csv('data/data2.csv'mengine='python')
2.2.3 读取其他文件
Excel和CSV是最常用的,其他文件读取简单了解,读取文件的大部分参数是通用的。
read_table(): 读取文本文件read_json(): 读取 JSON 文件
2.2.4 存储数据
在Pandas中存储数据直接使用to_xxx()方法即可,默认会把索引也存储进去,如果不需要索引,可以通过index=False参数去掉索引。
data2.to_excel('data/new_data2.xlsx', index=False)
2.3 DataFrame 的属性
columns:列索引index:行索引values:数据值
print(data2)
print('\n列索引:', data2.columns)
print('行索引:', data2.index)
print('数据值:\n', data2.values)
姓名 语文 数学 英语
0 张三 88 100 90
1 李四 82 65 52
2 王五 80 92 60
列索引: Index(['姓名', '语文', '数学', '英语'], dtype='object')
行索引: RangeIndex(start=0, stop=3, step=1)
数据值:
[['张三' 88 100 90]
['李四' 82 65 52]
['王五' 80 92 60]]
dtypes:每一列的数据类型
data2.dtypes
姓名 object
语文 int64
数学 int64
英语 int64
dtype: object
ndim:维度shape:形状size:元素个数
print('维度', data2.ndim)
print('形状', data2.shape)
print('元素个数', data2.size)
维度 2
形状 (3, 4)
元素个数 12
2.4 DataFrame 的方法
info():查看DataFrame的基本信息
data2.info()
RangeIndex: 3 entries, 0 to 2
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 姓名 3 non-null object
1 语文 3 non-null int64
2 数学 3 non-null int64
3 英语 3 non-null int64
dtypes: int64(3), object(1)
memory usage: 224.0+ bytes
describe():获取统计性描述信息
DataFrame也有很多统计性描述信息的方法,和Series一致,此处不再赘述。不过多了一个axis参数控制聚合轴向:
axis=0:按列进行统计axis=1:按行进行统计
data2.describe()
| 语文 | 数学 | 英语 | |
|---|---|---|---|
| count | 3.000000 | 3.000000 | 3.000000 |
| mean | 83.333333 | 85.666667 | 67.333333 |
| std | 4.163332 | 18.339393 | 20.033306 |
| min | 80.000000 | 65.000000 | 52.000000 |
| 25% | 81.000000 | 78.500000 | 56.000000 |
| 50% | 82.000000 | 92.000000 | 60.000000 |
| 75% | 85.000000 | 96.000000 | 75.000000 |
| max | 88.000000 | 100.000000 | 90.000000 |
cumsum():累计和cumprod():累计积cummax():累计最大值cummin():累计最小值
data2.cumsum()
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 张三李四 | 170 | 165 | 142 |
| 2 | 张三李四王五 | 250 | 257 | 202 |
data2.cummin()
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 张三 | 82 | 65 | 52 |
| 2 | 张三 | 80 | 65 | 52 |
head(n):查看前n行数据,默认n=5tail(n):查看后n行数据,默认n=5
data2.head(2)
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
data2.tail(3)
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
sort_index():根据索引排序,默认升序sort_values():根据值排序,默认升序
使用ascending=False参数可以实现降序排列。
data2.sort_index(ascending=False)
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 2 | 王五 | 80 | 92 | 60 |
| 1 | 李四 | 82 | 65 | 52 |
| 0 | 张三 | 88 | 100 | 90 |
data2.sort_values('英语')
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
| 0 | 张三 | 88 | 100 | 90 |
3 Index 对象
Index用来唯一标识 DataFrame 中的每一行数据,就像数据库表中的主键一样,但它不强制要求是唯一的,类似于一维数组,存储着用于标记各行数据的标签。
3.1 Index 的特点
- 标签:作为行标签使用,用来访问特定行
df.loc[行标签] - 对齐:两个
DataFrame之间运算(比如加法、合并等)时,Pandas根据Index和Column自动将数据对齐,而不需要行和列的顺序相同 - 不可变性:
Index对象一旦创建,不允许被修改,所有修改索引必须整体修改
3.2 Index 常用操作
data2
| 姓名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
index:查看index
data2.index
RangeIndex(start=0, stop=3, step=1)
set_index():将普通列设为行索引。
df.set_index(keys, drop=True, inplace=False)
- keys:新索引的列名或列名列表
- drop:用于创建新索引的列是否从表中删除,默认为True
- inplace:是否在原表修改
data3 = data2.set_index('姓名')
data3
| 语文 | 数学 | 英语 | |
|---|---|---|---|
| 姓名 | |||
| 张三 | 88 | 100 | 90 |
| 李四 | 82 | 65 | 52 |
| 王五 | 80 | 92 | 60 |
reset_index:set_index的逆操作,将索引重置为普通列,并且创建一个新的RangeIndex作为索引。
df.reset_index(drop=False, name=None, inplace=False)
- drop:是否删除原有索引,不转化为普通列,默认为False
- names:指定转为为普通列之后的名称
- inplace:是否在原表修改
data3.reset_index(names='大名')
| 大名 | 语文 | 数学 | 英语 | |
|---|---|---|---|---|
| 0 | 张三 | 88 | 100 | 90 |
| 1 | 李四 | 82 | 65 | 52 |
| 2 | 王五 | 80 | 92 | 60 |
浙公网安备 33010602011771号