文章目录
一、Pandas简介
1.1 为什么要学习Pandas?
- numpy已经能够帮助我们处理数据,能结合matplotlib解决我们数据分析的问题,那么pandas学习的目的在什么地方呢?
- numpy能够帮我们处理处理数值型数据,但是这还不够,很多时候,我们的数据除了数值之外,还有字符串,还有时间序列等。所以,pandas出现了
1.2 什么是Pandas
pandas的名称来自于面板数据(panel data)
Pandas是一个强大的分析结构化数据的工具集,基于Numpy构建,提供了高级数据结构和数据操作工具,它是使Python成为强大而高效的数据分析环境的重要因素之一
- 一个强大的分析和操作大型结构化数据集所需的工具集
- 基础是Numpy,提供了高性能矩阵的运算
- 提供了大量能够快速便捷地处理数据的函数和方法
- 应用于数据挖掘,数据分析
- 提供数据清洗功能
1.3 Pandas的安装
conda install pandas
二、Pandas的数据结构
import pandas as pd
Pandas有两个最主要的也是最重要的数据结构:Series 和 DataFrame
2.1 Series简介
series 是一种一维标记的数组型对象,能够保存任何数据类型(int,str,float,python object…),包含了数据标签,称为索引
- 类似一维数组的对象1,index = [‘名字’,‘年龄’,‘班级’]
- 由数据和索引组成
- 索引(index)在左,数据(values)在右
- 索引如果不手动指定,会自动创建
2.2 Series创建
2.2.1 通过list创建
# 1. 通过list创建
s1 = pd.Series([1,2,3,4,5])
print(s1,'\n')
print(type(s1))
0 1
1 2
2 3
3 4
4 5
dtype: int64
<class 'pandas.core.series.Series'>
2.2.2 通过numpy数组创建
# 2. 通过numpy数组创建
import numpy as np
arr1 = np.arange(1,6)
print(arr1.dtype,'\n')
print(pd.Series(arr1))
int32
0 1
1 2
2 3
3 4
4 5
dtype: int32
# 手动指定index,但注意:索引长度与数据长度需要相同
s2 = pd.Series(arr1,index=['a','b','c','d','e'])
print(s2)
a 1
b 2
c 3
d 4
e 5
dtype: int32
# 获取series的index值
print(s2.index,'\n')
# 获取series的value值
print(s2.values,'\n')
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
[1 2 3 4 5]
- 通过字典创建
dict_ = {'name':'李玲','age':18,'class':'三班'}
# 当传入字典类型数据时,可以在参数index传入key的list数据规定顺序
# 同时如果list中设置了没有的key值,则series中会默认填充:key--->NAN
s3 = pd.Series(dict_,index=['age','name','class','sex'])
print(s3)
age 18
name 李玲
class 三班
sex NaN
dtype: object
2.3 Series的基本用法
2.3.1 isnull 和 notnull 检查缺失值
print(s3)
s3.isnull() # 判断值是否为空
age 18
name 李玲
class 三班
sex NaN
dtype: object
age False
name False
class False
sex True
dtype: bool
s3.notnull() # 判断值是否不为空
age True
name True
class True
sex False
dtype: bool
2.3.2 通过索引获取数据(简要介绍)
print(s3.index,'\n')
print(s3.values)
Index(['age', 'name', 'class', 'sex'], dtype='object')
[18 '李玲' '三班' nan]
# 下标
print(s3,'\n')
# 取单个值
print(s3[1],'\n') # 输出第二行对应的value值
# 取多个值
print(s3[[1,3]],'\n')
age 18
name 李玲
class 三班
sex NaN
dtype: object
李玲
name 李玲
sex NaN
dtype: object
# 标签名
print(s3,'\n')
# 取单个数据
print(s3['age'],'\n')
# 取多个数据
print(s3[['age','sex']],'\n')
age 18
name 李玲
class 三班
sex NaN
dtype: object
18
age 18
sex NaN
dtype: object
# 下标或标签值切片
print(s3,'\n')
# 使用下标切(左闭右开)
print(s3[1:3],'\n')
# 使用index切(左闭右闭)
print(s3['age':'class'],'\n')
age 18
name 李玲
class 三班
sex NaN
dtype: object
name 李玲
class 三班
dtype: object
age 18
name 李玲
class 三班
dtype: object
# 布尔索引
print(s2,'\n')
print(s2[s2>3])
a 1
b 2
c 3
d 4
e 5
dtype: int32
d 4
e 5
dtype: int32
2.3.3 索引与数据的对应关系不被运算结果影响
print(s2,'\n')
print(s2*2)
a 1
b 2
c 3
d 4
e 5
dtype: int32
a 2
b 4
c 6
d 8
e 10
dtype: int32
2.3.4 name属性
print(s2,'\n')
s2.name = 'temp' # series对象名
s2.index.name = 'year' # 对象索引名
print(s2)
a 1
b 2
c 3
d 4
e 5
dtype: int32
year
a 1
b 2
c 3
d 4
e 5
Name: temp, dtype: int32
print(s2,'\n')
print(s2.head(3)) # 默认获取前5行
print(s2.tail(3)) # 默认获取后5行
year
a 1
b 2
c 3
d 4
e 5
Name: temp, dtype: int32
year
a 1
b 2
c 3
Name: temp, dtype: int32
year
c 3
d 4
e 5
Name: temp, dtype: int32
2.4 DataFrame介绍
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同类型的值。DataFrame既有行索引也有列索引,它可以被看做是由Series组成的字典(共用同一个索引),数据是以二维结构存放的
- 类似多维数组/表格数据(如,excel,R中data.frame)
- 每列数据可以是不同的类型
- 索引包括列索引和行索引
2.5 DataFrame创建
import numpy as np
import pandas as pd
2.5.1 使用字典的创建方式:(将key:value当做列向量水平拼接)
- 数组、列表或元组构成的字典构造dataframe
- Series构成的字典构造dataframe
- 字典构成的字典构成dataframe
# 1. 数组、列表或元组构成的字典构造dataframe
# 构造一个字典
data = {'a':[1,2,3,4],
'b': [5,6,7,8],
'c': np.arange(9,13)}
# 构造dataframe
frame = pd.DataFrame(data)
print(frame)
a b c
0 1 5 9
1 2 6 10
2 3 7 11
3 4 8 12
# index查看行索引
frame.index
RangeIndex(start=0, stop=4, step=1)
# columns属性查看列索引
frame.columns
Index(['a', 'b', 'c'], dtype='object')
# value属性
frame.values
array([[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11],
[ 4, 8, 12]], dtype=int64)
# 指定index
frame = pd.DataFrame(data,index=['A','B','C','D'])
print(frame)
a b c
A 1 5 9
B 2 6 10
C 3 7 11
D 4 8 12
# 指定列索引
frame = pd.DataFrame(data,index=['A','B','C','D'],columns=['1','2','3'])
print(frame,'\n')
# 字典中没有key的一列会填充NAN
frame = pd.DataFrame(data,index=['A','B','C','D'],columns=['a','b','c','d'])
print(frame,'\n')
1 2 3
A NaN NaN NaN
B NaN NaN NaN
C NaN NaN NaN
D NaN NaN NaN
a b c d
A 1 5 9 NaN
B 2 6 10 NaN
C 3 7 11 NaN
D 4 8 12 NaN
# 2. Series构成的字典构造dataframe
pd1 = pd.DataFrame({'a':pd.Series(np.arange(3)),
'b':pd.Series(np.arange(3,5))})
pd1
a | b | |
---|---|---|
0 | 0 | 3.0 |
1 | 1 | 4.0 |
2 | 2 | NaN |
# 3. 字典构成的字典构成dataframe
data1 = {
'a':{'apple':3.6,'banana':5.6},
'b':{'apple':3,'banana':5},
'c':{'apple1':3.2}
}
pd2 = pd.DataFrame(data1)
print(pd2)
a b c
apple 3.6 3.0 NaN
banana 5.6 5.0 NaN
apple1 NaN NaN 3.2
2.5.2 使用列表的创建方式:(将元素当做行向量垂直拼接)
- 2D ndarray 构造dataframe
- 字典构成的列表构造dataframe
- Series构成的列表构造dataframe
# 1. 2D ndarray 构造dataframe
# 构造二维数组对象
arr1 = np.arange(12).reshape((4,3))
frame1 = pd.DataFrame(arr1,index=['A','B','C','D'],columns=['a','b','c'])
print(frame1)
a b c
A 0 1 2
B 3 4 5
C 6 7 8
D 9 10 11
# 2. 字典构成的列表构造dataframe
l1 = [{'apple':3.6,'banana':5.6},{'apple':3,'banana':5},{'apple1':3.2}]
frame1 = pd.DataFrame(l1)
print(frame1)
apple banana apple1
0 3.6 5.6 NaN
1 3.0 5.0 NaN
2 NaN NaN 3.2
# 3. Series构成的列表构造dataframe
l2 = [pd.Series(np.random.rand(3)),pd.Series(np.random.rand(2))]
pd4 = pd.DataFrame(l2)
print(pd4)
0 1 2
0 0.866441 0.592822 0.915449
1 0.495508 0.984747 NaN
2.6 DataFrame的基本用法
2.6.1 T转置
pd5 = pd.DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=['A','B','C'])
print(pd5,'\n')
# 和numpy一样,进行转置 行和列转置
print(pd5.T)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
a b c
A 0 3 6
B 1 4 7
C 2 5 8
2.6.2 通过列索引获取列数据(Series)
a = pd5['A']
print(a,'\n')
print(type(a))
a 0
b 3
c 6
Name: A, dtype: int32
<class 'pandas.core.series.Series'>
# 增加一列数据
pd5['D'] = [1,2,3]
print(pd5)
A B C D
a 0 1 2 1
b 3 4 5 2
c 6 7 8 3
# 删除一列
del(pd5['D'])
print(pd5)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
2.6.3 DataFrame的切片
DataFrame的切片等操作与Series类似,均是使用Index进行操作。只是针对的是行向量,且返回的数据是DataFrame类型
三、Pandas的索引操作
3.1 索引对象 Index
3.1.1 Series和DataFrame中的索引都是Index对象
ser_obj = pd.Series(range(5),index=['a','b','c','d','e'])
df_obj = pd.DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['A','B','C'])
print(type(ser_obj.index),'\n')
print(type(df_obj.index),'\n')
print(df_obj.index)
<class 'pandas.core.indexes.base.Index'>
<class 'pandas.core.indexes.base.Index'>
Index(['a', 'b', 'c'], dtype='object')
3.1.2 索引对象不可变,保证了数据的安全
ser_obj.index[0] = 2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
C:\Users\GAOYON~1\AppData\Local\Temp/ipykernel_4764/2087875170.py in <module>
----> 1 ser_obj.index[0] = 2
d:\application\anaconda3\envs\data_analysis\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
4583 @final
4584 def __setitem__(self, key, value):
-> 4585 raise TypeError("Index does not support mutable operations")
4586
4587 def __getitem__(self, key):
TypeError: Index does not support mutable operations
3.1.3 常见的Index种类
Index,索引
Int64Index,整数索引
MultiIndex,层级索引
DatetimeIndex,时间戳索引
3.2 索引的一些基本操作
3.2.1 重新索引
print(ser_obj)
# reindex 创建一个符合新索引的新对象
ps2 = ser_obj.reindex(['a','b','c','d','e','f'])
print(ps2)
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 0.0
b 1.0
c 2.0
d 3.0
e 4.0
f NaN
dtype: float64
print(df_obj)
# reindex 创建一个符合新行索引的新对象
df2 = df_obj.reindex(['a','b','c','d'])
print(df2)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
A B C
a 0.0 1.0 2.0
b 3.0 4.0 5.0
c 6.0 7.0 8.0
d NaN NaN NaN
# 列索引重建
df3 = df_obj.reindex(columns=['C','B','A'])
print(df3)
C B A
a 2 1 0
b 5 4 3
c 8 7 6
3.2.2 增加的操作
print(ser_obj)
a 0
b 1
c 2
d 3
e 4
dtype: int64
# 在原series对象上直接添加
ser_obj['f'] = 9
print(ser_obj)
a 0
b 1
c 2
d 3
e 4
f 9
dtype: int64
# append返回一个新的series对象,实现对原series对象的增加操作
# append不改变原对象的值
s1 = pd.Series({'g':999})
ps3 = ser_obj.append(s1)
print(ser_obj,'\n')
print(ps3)
a 0
b 1
c 2
d 3
e 4
f 9
dtype: int64
a 0
b 1
c 2
d 3
e 4
f 9
g 999
dtype: int64
print(df_obj)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
# 在原dataframe对象上直接添加(列向量)
df_obj['D'] = 1 # 广播机制
print(df_obj)
A B C D
a 0 1 2 1
b 3 4 5 1
c 6 7 8 1
# 在原dataframe新增指定位置的列数据(插入操作)
df_obj.insert(0,'E',[9,99,999])
print(df_obj)
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
# DataFrame增加行
print(df_obj)
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
# 标签索引 loc
df_obj.loc['d'] = [1,2,3,4,5]
print(df_obj)
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
d 1 2 3 4 5
# append方法,新建一个DataFrame对象实现对原DataFrame对象的增加操作
# append仅能对dataframe数据增加行数据
df2 = pd.DataFrame(np.arange(15).reshape((3,5)),columns=['E','A','B','C','D'])
df3 = df_obj.append(df2)
print(df_obj,'\n')
print(df2,'\n')
print(df3)
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
E A B C D
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3.2.3 删除操作
print(ser_obj)
a 0
b 1
c 2
d 3
e 4
dtype: int64
# 对原Series对象进行删除操作
del ser_obj['e']
print(ser_obj)
a 0
b 1
c 2
d 3
dtype: int64
print(df_obj,'\n')
# 对原DataFrame对象进行删除列操作
del df_obj['D']
print(df_obj)
E A B C D
a 9 0 1 2 1
b 99 3 4 5 1
c 999 6 7 8 1
d 1 2 3 4 1
E A B C
a 9 0 1 2
b 99 3 4 5
c 999 6 7 8
d 1 2 3 4
# drop 删除轴上数据(返回删除数据后的对象,不改变原对象)
print(ser_obj,'\n')
# series删除一条数据
s3 = ser_obj.drop('d')
print(ser_obj,'\n')
print(s3)
a 0
b 1
c 2
d 3
dtype: int64
a 0
b 1
c 2
d 3
dtype: int64
a 0
b 1
c 2
dtype: int64
print(ser_obj,'\n')
# drop 删除series多条数据
print(ser_obj.drop(['a','d']))
a 0
b 1
c 2
d 3
dtype: int64
b 1
c 2
dtype: int64
# drop删除dataframe数据
print(df_obj,'\n')
# 删除单条(行数据)
print(df_obj.drop('a'),'\n')
# 删除多条(行数据)
print(df_obj.drop(['a','b']))
E A B C
a 9 0 1 2
b 99 3 4 5
c 999 6 7 8
d 1 2 3 4
E A B C
b 99 3 4 5
c 999 6 7 8
d 1 2 3 4
E A B C
c 999 6 7 8
d 1 2 3 4
# drop删除dataframe数据
print(df_obj,'\n')
# 删除单条(列数据)
print(df_obj.drop('E',axis=1),'\n')
# 删除多条(列数据)
print(df_obj.drop(['E','A'],axis=1))
E A B C
a 9 0 1 2
b 99 3 4 5
c 999 6 7 8
d 1 2 3 4
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 2 3 4
B C
a 1 2
b 4 5
c 7 8
d 3 4
# drop方法的inplace属性,设置为True时,会在原对象上进行操作,方法不会返回对象
print(df_obj,'\n')
df_obj.drop('d',inplace=True)
print(df_obj,'\n')
E A B C
a 9 0 1 2
b 99 3 4 5
c 999 6 7 8
d 1 2 3 4
E A B C
a 9 0 1 2
b 99 3 4 5
c 999 6 7 8
3.2.4 修改操作
# 新建对象
ser_obj = pd.Series(range(5),index=['a','b','c','d','e'])
df_obj = pd.DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['A','B','C'])
print(ser_obj,'\n')
print(df_obj)
a 0
b 1
c 2
d 3
e 4
dtype: int64
A B C
a 0 1 2
b 3 4 5
c 6 7 8
# series的修改
ser_obj['a'] = 999
print(ser_obj)
a 999
b 1
c 2
d 3
e 4
dtype: int64
ser_obj[0] = 888
print(ser_obj)
a 888
b 1
c 2
d 3
e 4
dtype: int64
# DataFrame对象修改
print(df_obj,'\n')
df_obj['A'] = 9 # 修改的列数据
print(df_obj)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
A B C
a 9 1 2
b 9 4 5
c 9 7 8
# dataframe.列 的形式
df_obj.A = 6
print(df_obj)
A B C
a 6 1 2
b 6 4 5
c 6 7 8
# dataframe使用标签索引loc,修改行数据
print(df_obj,'\n')
df_obj.loc['a'] = [7,7,7]
print(df_obj)
A B C
a 6 1 2
b 6 4 5
c 6 7 8
A B C
a 7 7 7
b 6 4 5
c 6 7 8
# dataframe使用标签索引loc,修改某一位置的数据
print(df_obj,'\n')
df_obj.loc['a','A'] = 999
print(df_obj)
A B C
a 7 7 7
b 6 4 5
c 6 7 8
A B C
a 999 7 7
b 6 4 5
c 6 7 8
3.2.5 查找数据
# Series
# 1. 行索引
print(ser_obj,'\n')
print(ser_obj['a'],'\n') # 使用行索引
print(ser_obj[0],'\n') # 使用位置索引
a 0
b 1
c 2
d 3
e 4
dtype: int64
0
0
# 2. 切片索引
print(ser_obj,'\n')
print(ser_obj[0:4],'\n') # 使用位置索引切片是:左闭右开
print(ser_obj['a':'e']) # 使用标签切片是:左闭右闭
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 0
b 1
c 2
d 3
dtype: int64
a 0
b 1
c 2
d 3
e 4
dtype: int64
# 3. 不连续索引
print(ser_obj,'\n')
print(ser_obj[['a','d']])
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 0
d 3
dtype: int64
# 4. 布尔索引
print(ser_obj,'\n')
print(ser_obj[ser_obj > 2])
a 0
b 1
c 2
d 3
e 4
dtype: int64
d 3
e 4
dtype: int64
# dataframe
print(df_obj,'\n')
# 获取单列数据
print(df_obj['A'],'\n')
# 获取单列数据
print(df_obj[['A','B']],'\n')
# 选取一个值
print(df_obj['A']['a'])
A B C
a 999 7 7
b 6 4 5
c 6 7 8
a 999
b 6
c 6
Name: A, dtype: int64
A B
a 999 7
b 6 4
c 6 7
999
# 2. dataframe的切片获取的是行向量
print(df_obj,'\n')
# 获取行数据
print(df_obj[:2])
A B C
a 0 1 2
b 3 4 5
c 6 7 8
A B C
a 0 1 2
b 3 4 5
3.3 高级索引
3.3.1 loc 标签索引
# 1. loc 标签索引
# loc是基于标签的索引自定义的索引名
print(ser_obj,'\n')
# 对于Series类型数据效果与普通切片一致,但必须传入标签索引
print(ser_obj['a':'c'],'\n')
print(ser_obj.loc['a':'c'],'\n')
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 0
b 1
c 2
dtype: int64
a 0
b 1
c 2
dtype: int64
# 对于DataFrame类型的数据
print(df_obj,'\n')
# 获取切片数据
# 第一个参数是索引行,第二个参数是索引列(均要传入标签索引)
print(df_obj.loc['a':'b','A':'C'])
A B C
a 0 1 2
b 3 4 5
c 6 7 8
A B C
a 0 1 2
b 3 4 5
3.3.2 iloc 位置索引
# 2. iloc 位置索引
# loc是基于标签的索引自定义的索引名
print(ser_obj,'\n')
# 对于Series类型数据效果与普通切片一致,但必须传入位置索引
print(ser_obj['a':'c'],'\n')
print(ser_obj.iloc[0:3],'\n')
a 0
b 1
c 2
d 3
e 4
dtype: int64
a 0
b 1
c 2
dtype: int64
a 0
b 1
c 2
dtype: int64
# 对于DataFrame类型的数据
print(df_obj,'\n')
# 获取切片数据
# 第一个参数是索引行,第二个参数是索引列(均要传入位置索引)
print(df_obj.iloc[0:2,0:2])
A B C
a 0 1 2
b 3 4 5
c 6 7 8
A B
a 0 1
b 3 4