Pandas的数据结构
numpy 给力教程
下一篇:pandas数据分析给力教程【完整版】(二)
导入pandas
1
2from pandas import Series
1、Series
Series是一种类似于一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
1)Series的创建
两种创建方式:
(1) 由列表或numpy数组创建,默认索引为0到N-1的整数型索引
由列表创建
1
2
3
4l = [1,2,3,4,5] s = Series(l, index=list('abcde')) s
1
2
3
4
5
6
7
8
9
10
11
12a 1 b 2 c 3 d 4 e 5 dtype: int64
1
2s.index
1
2Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
1
2s.values
1
2array([1, 2, 3, 4, 5], dtype=int64)
还可以通过设置index参数指定索引
1
2
3s.index = [1,2,3,4,5] s
1
2
3
4
5
6
7
8
9
10
11
121 1 2 2 3 3 4 4 5 5 dtype: int64
1
2
3s[1] = 10 s
1
2
3
4
5
6
7
8
9
10
11
121 10 2 2 3 3 4 4 5 5 dtype: int64
1
2
3
4n = np.arange(0,10) s = Series(n.copy()) s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
220 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int32
1
2
3s[0] = 8 s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
220 8 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int32
特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
(2) 由字典创建
1
2
3
4# 字典的key对应Series的索引 s = Series({'a':1, 'b':2, 'c':3, 'd': 4}) s
1
2
3
4
5
6
7
8
9
10a 1 b 2 c 3 d 4 dtype: int64
============================================
练习1:
使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300
============================================
1
2
3
4# 字典 s1 = Series({'语文': 150, '数学': 150, '英语': 150, '理综': 300}) s1
1
2
3
4
5data = [150, 150, 150, 300] index = ['语文', '数学', '英语', '理综'] s1 = Series(data=data,index=index) s1
1
2
3
4
5
6
7
8
9
10语文 150 数学 150 英语 150 理综 300 dtype: int64
2)Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。索引分为显示索引和隐式索引:
(1) 显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
注意,此时是闭区间
1
2s
1
2
3# 不推荐 s['a']
1
21
1
2
3#推荐的写法 s.loc['a']
1
21
1
2
3s.loc['a': 'c'] # 注意: 区间 是全闭区间
1
2
3
4
5
6
7
8a 1 b 2 c 3 dtype: int64
1
2s['a': 'c']
1
2
3
4
5
6
7
8a 1 b 2 c 3 dtype: int64
(2) 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐)
注意,此时是半开区间
1
2s
1
2
3
4
5
6
7
8
9
10a 1 b 2 c 3 d 4 dtype: int64
1
2s[0]
1
21
1
2
3s = Series(np.arange(10)) s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
220 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int32
1
2
3s.index = np.arange(1,11) s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
221 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 dtype: int32
1
2s[1]
1
20
1
2
3# 隐式索引的推荐写法 s.iloc[0]
1
20
1
2s.iloc[0:3] # 隐式索引的切片是左闭右开的.
1
2
3
4
5
6
7
81 0 2 1 3 2 dtype: int32
============================================
练习2:
使用多种方法对练习1创建的Series s1进行索引和切片:
索引:
数学 150
切片:
语文 150
数学 150
英语 150
============================================
1
2s1
1
2s1.loc['数学']
1
2s1.iloc[1]
1
2s1.loc[['数学']] # 再套一层中括号,返回原来的数据类型
1
2s1.loc[['数学', '理综']]
1
2s1.iloc[[1, 3]]
1
2s1.loc['语文': '英语']
1
2s1.iloc[0: 3]
3)Series的基本概念
可以把Series看成一个定长的有序字典
可以通过shape,size,index,values等得到series的属性
1
2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
221 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 dtype: int32
1
2s.shape
1
2s.size
1
2s.index
1
2s.values
可以通过head(),tail()快速查看Series对象的样式
1
2s.head(3)
1
2
3
4
5
6
7
81 0 2 1 3 2 dtype: int32
1
2s.tail(4)
1
2
3
4
5
6
7
8
9
107 6 8 7 9 8 10 9 dtype: int32
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
1
2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 0.0 2 1.0 3 2.0 4 3.0 5 4.0 6 5.0 7 6.0 8 7.0 9 8.0 10 9.0 0 NaN dtype: float64
1
2s.loc[0] = np.nan
1
2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 0.0 2 1.0 3 2.0 4 3.0 5 4.0 6 5.0 7 6.0 8 7.0 9 8.0 10 9.0 0 NaN Name: Name, dtype: float64
可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
1
2pd.isnull(s)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 False 2 False 3 False 4 False 5 False 6 False 7 False 8 False 9 False 10 False 0 True dtype: bool
1
2pd.notnull(s)
1
2s.isnull()
1
2s.notnull()
Series对象本身及其实例都有一个name属性
1
2
3s.name = 'Series s' s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 0.0 2 1.0 3 2.0 4 3.0 5 4.0 6 5.0 7 6.0 8 7.0 9 8.0 10 9.0 0 NaN Name: Series s, dtype: float64
1
2
3Series.name = 'Name' s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 0.0 2 1.0 3 2.0 4 3.0 5 4.0 6 5.0 7 6.0 8 7.0 9 8.0 10 9.0 0 NaN Name: Name, dtype: float64
4)Series的运算
(1) 适用于numpy的数组运算也适用于Series
1
2s + 1
(2) Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
1
2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
241 0.0 2 1.0 3 2.0 4 3.0 5 4.0 6 5.0 7 6.0 8 7.0 9 8.0 10 9.0 0 NaN Name: Name, dtype: float64
1
2
3s2 = Series(np.random.randint(0, 10, size=11), index=np.arange(3, 14)) s2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
243 0 4 5 5 3 6 9 7 1 8 9 9 1 10 7 11 9 12 6 13 1 dtype: int32
1
2
3s + s2 # 相同的索引进行运算,不同的索引补NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
300 NaN 1 NaN 2 NaN 3 2.0 4 8.0 5 7.0 6 14.0 7 7.0 8 16.0 9 9.0 10 16.0 11 NaN 12 NaN 13 NaN dtype: float64
- 注意:要想保留所有的index,则需要使用.add()函数
1
2
3# 使用pandas封装的运算函数,保留所有index对应value s.add(s2, fill_value=0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
300 NaN 1 0.0 2 1.0 3 2.0 4 8.0 5 7.0 6 14.0 7 7.0 8 16.0 9 9.0 10 16.0 11 9.0 12 6.0 13 1.0 dtype: float64
============================================
练习3:
-
想一想Series运算和ndarray运算的规则有什么不同?
-
新建另一个索引包含“文综”的Series s2,并与s1进行多种算术操作。思考如何保存所有数据。
============================================
ndarray有广播机制,Series没有广播机制,Series只是根据相同的索引进行运算
1
2
3s2 = Series({'语文': 108, '数学': 149, '英语': 138, '文综': 268}) s2
1
2
3
4
5
6
7
8
9
10语文 108 数学 149 英语 138 文综 268 dtype: int64
1
2s2.sum()
1
2663
1
2
3s1 + s2
1
2
3
4
5
6
7
8
9
10
11
12数学 299.0 文综 NaN 理综 NaN 英语 288.0 语文 258.0 dtype: float64
1
2s1.add(s2, fill_value=0) / 2
1
2
3
4
5
6
7
8
9
10
11
12数学 149.5 文综 134.0 理综 150.0 英语 144.0 语文 129.0 dtype: float64
2、DataFrame
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引),由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到二维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values(numpy的二维数组)
1)DataFrame的创建
最常用的方法是传递一个字典来创建,DataFrame以字典的键作为每一列的名称,以字典的值(一个数组)作为每一列的值
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
1
2
3from pandas import DataFrame
分块创建
1
2
3
4
5
6data = np.random.randint(0,150, size=(4,4)) index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语','python'] df = DataFrame(data=data, index=index, columns=columns) df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 104 | 26 | 38 | 52 |
李四 | 11 | 104 | 88 | 41 |
王五 | 38 | 119 | 36 | 139 |
赵六 | 67 | 93 | 21 | 130 |
使用字典创建
1
2
3
4df = DataFrame({'语文': np.random.randint(0,150, size=4), '数学': np.random.randint(0,150, size=4), '英语': np.random.randint(0,150, size=4), 'python': np.random.randint(0,150, size=4)},) df.index = ['张三', '李四', '王五', '赵六'] df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
DataFrame属性:values、columns、index、shape
1
2df.values
1
2df.columns
1
2df.index
1
2df.shape
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为ddd:
1
2
3
4
5
6
7
8
9
10
11
12张三 李四 语文 150 0 数学 150 0 英语 150 0 理综 300 0
============================================
1
2
3
4
5
6# 字典 ddd = DataFrame({'张三': [150]* 3 + [300], '李四': [0]* 4}) ddd.index = ['语文', '数学', '英语', '理综'] ddd
1
2
3
4
5
6data = [[150,0]] * 3 + [[300, 0]] index = ['语文', '数学', '英语', '理综'] columns = ['张三', '李四'] ddd = DataFrame(data=data, index=index, columns=columns) ddd
2)DataFrame的索引
(1) 对列进行索引
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series,返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 118 | 12 | 53 | 12 |
李四 | 48 | 34 | 81 | 54 |
王五 | 32 | 58 | 80 | 133 |
赵六 | 107 | 25 | 25 | 42 |
1
2df['语文']
1
2
3
4
5
6
7
8
9
10张三 118 李四 48 王五 32 赵六 107 Name: 语文, dtype: int32
1
2df.语文
1
2
3
4
5
6
7
8
9
10张三 118 李四 48 王五 32 赵六 107 Name: 语文, dtype: int32
1
2
3
4# 新增一列 df['计算机'] = np.random.randint(0,150, size=4) df
语文 | 数学 | 英语 | python | 计算机 | |
---|---|---|---|---|---|
张三 | 118 | 12 | 53 | 12 | 110 |
李四 | 48 | 34 | 81 | 54 | 131 |
王五 | 32 | 58 | 80 | 133 | 132 |
赵六 | 107 | 25 | 25 | 42 | 129 |
1
2
3# 新增一列的时候不能使用属性的写法 df.理综 = np.random.randint(0,150, size=4)
1
2
3C:UsersADMINI~1AppDataLocalTemp/ipykernel_7776/1072798280.py:2: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access df.理综 = np.random.randint(0,150, size=4)
1
2df
语文 | 数学 | 英语 | python | 计算机 | |
---|---|---|---|---|---|
张三 | 118 | 12 | 53 | 12 | 110 |
李四 | 48 | 34 | 81 | 54 | 131 |
王五 | 32 | 58 | 80 | 133 | 132 |
赵六 | 107 | 25 | 25 | 42 | 129 |
(2) 对行进行索引
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
1
2
3# 显式写法 df.loc['张三']
1
2
3
4
5
6
7
8
9
10
11
12语文 118 数学 12 英语 53 python 12 计算机 110 Name: 张三, dtype: int32
1
2df.iloc[1]
(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]
- 使用values属性(二维numpy数组)
1
2
3
4# 先列后行 # 链式索引的赋值,不要这么写 df['英语']['李四'] = 88
1
2df
1
2
3# 先行后列 df.loc['李四'].loc['英语']
1
2
3# 推荐写法 df.loc['李四', '英语']
1
2df.iloc[1, 2]
链式索引不推荐.
1
2df.loc[['李四']]
语文 | 数学 | 英语 | python | 计算机 | |
---|---|---|---|---|---|
李四 | 48 | 34 | 81 | 54 | 131 |
3)DataFrame切片
(1)列切片
1
2df['数学': 'python'] # 这样写不是对列切片
语文 | 数学 | 英语 | python |
---|
1
2df.loc[:, '数学': 'python']
数学 | 英语 | python | |
---|---|---|---|
张三 | 12 | 53 | 12 |
李四 | 34 | 81 | 54 |
王五 | 58 | 80 | 133 |
赵六 | 25 | 25 | 42 |
1
2df.iloc[:, 1:3]
数学 | 英语 | |
---|---|---|
张三 | 110 | 143 |
李四 | 85 | 53 |
王五 | 32 | 29 |
赵六 | 23 | 50 |
1
2df[['数学', '英语', 'python']]
数学 | 英语 | python | |
---|---|---|---|
张三 | 110 | 143 | 89 |
李四 | 85 | 53 | 138 |
王五 | 32 | 29 | 141 |
赵六 | 23 | 50 | 50 |
1
2df.iloc[:, 0:3]
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 30 | 110 | 143 |
李四 | 116 | 85 | 53 |
王五 | 28 | 32 | 29 |
赵六 | 91 | 23 | 50 |
(2)行切片
1
2df['李四': '王五'] # 全闭的区间
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
DataFrame 索引总结
1,行索引用.loc, 列索索引用中括号
2,对元素的索引,先索引行,再索引列. df.loc[index, columns]
3,如果还想返回DataFrame,那么使用两层中括号
注意:
- 直接使用中括号的时候
- 索引表示的是列索引
- 切片表示的是行切片
- 不要使用链式索引
============================================
练习5:
使用多种方法对ddd进行索引和切片,并比较其中的区别
============================================
1
2ddd
1
2
3
4
5
6
7--------------------------------------------------------------------------- NameError Traceback (most recent call last) C:UsersADMINI~1AppDataLocalTemp/ipykernel_7776/2469631560.py in <module> ----> 1 ddd NameError: name 'ddd' is not defined
1,索引张三的英语成绩(要求返回的还是一个DataFrame)
2,切片,切语文到数学的成绩
3,对李四的英语成绩进行赋值,赋值为108
1
2ddd.loc[['语文'], ['张三']]
1
2ddd['语文': '数学']
1
2ddd.loc['语文': '数学']
1
2ddd.iloc[0:2]
1
2ddd.loc['英语', '李四'] = 108
4)DataFrame的运算
(1)DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
DataFrame和单个数字进行计算
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
1
2df + 1
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 31 | 111 | 144 | 90 |
李四 | 117 | 86 | 54 | 139 |
王五 | 29 | 33 | 30 | 142 |
赵六 | 92 | 24 | 51 | 51 |
DataFrame和DataFrame进行计算
1
2
3
4
5
6
7# DataFrame和DataFrame之间的运算:行列索引全部一致才运算,不一致补NaN data = np.random.randint(0,150, size=(4,4)) index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语','python'] df2 = DataFrame(data=data, index=index, columns=columns) df2
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 142 | 3 | 84 | 72 |
李四 | 77 | 38 | 46 | 43 |
王五 | 3 | 37 | 84 | 127 |
赵六 | 142 | 48 | 24 | 80 |
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
1
2
3df2.loc['田七'] = np.random.randint(0,150, size=4) df2
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 75 | 91 | 81 | 88 |
李四 | 133 | 1 | 128 | 81 |
王五 | 13 | 86 | 92 | 50 |
赵六 | 51 | 64 | 23 | 113 |
田七 | 146 | 58 | 20 | 42 |
1
2df + df2
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 105.0 | 201.0 | 224.0 | 177.0 |
李四 | 249.0 | 86.0 | 181.0 | 219.0 |
王五 | 41.0 | 118.0 | 121.0 | 191.0 |
田七 | NaN | NaN | NaN | NaN |
赵六 | 142.0 | 87.0 | 73.0 | 163.0 |
1
2df.add(df2, fill_value=0)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 105.0 | 201.0 | 224.0 | 177.0 |
李四 | 249.0 | 86.0 | 181.0 | 219.0 |
王五 | 41.0 | 118.0 | 121.0 | 191.0 |
田七 | 146.0 | 58.0 | 20.0 | 42.0 |
赵六 | 142.0 | 87.0 | 73.0 | 163.0 |
下面是Python 操作符与pandas操作函数的对应表:
Python Operator | Pandas Method(s) |
---|---|
+ | add() |
- | sub(), subtract() |
* | mul(), multiply() |
/ | truediv(), div(), divide() |
// | floordiv() |
% | mod() |
** | pow() |
(2) Series与DataFrame之间的运算
【重要】
- 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。
- 使用pandas操作函数:
- axis=0:以列为单位操作(参数必须是列),对所有列都有效。
- axis=1:以行为单位操作(参数必须是行),对所有行都有效。
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
1
2
3s = Series(data=np.random.randint(0,150,size=5), index=['语文', '数学', '英语', 'python', '计算机']) s
1
2
3
4
5
6
7
8
9
10
11
12语文 140 数学 114 英语 90 python 82 计算机 9 dtype: int32
1
2df + s # 直接进行运算,观察DataFrame的列索引和Series的索引是否一致,一致就进行相应的运算
python | 数学 | 英语 | 计算机 | 语文 | |
---|---|---|---|---|---|
张三 | 171 | 224 | 233 | NaN | 170 |
李四 | 220 | 199 | 143 | NaN | 256 |
王五 | 223 | 146 | 119 | NaN | 168 |
赵六 | 132 | 137 | 140 | NaN | 231 |
1
2
3s = Series(data=np.random.randint(0,150,size=4), index=['张三', '李四', '王五', '赵六']) s
1
2
3
4
5
6
7
8
9
10张三 122 李四 109 王五 84 赵六 45 dtype: int32
1
2
3df + s # 使用运算符的默认操作是DataFrame的列索引和Series的列索引进行比较
python | 张三 | 数学 | 李四 | 王五 | 英语 | 语文 | 赵六 | |
---|---|---|---|---|---|---|---|---|
张三 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
李四 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
王五 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
赵六 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1
2df.add(s, axis=0) # 使用axis改变运算的方向
归纳总结
1,DataFrame和单个数字运算,每个元素分别运算
2,DataFrame和DataFrame运算,相同的行列索引进行运算,不同索引补NaN
3,DataFrame和Series运算,使用运算符的时候,默认比较DataFrame的列索引和Series的索引
4,如果想保留原始数据,或者改变运算的方向,使用pandas封装的方法
============================================
练习6:
-
假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
-
假设张三期中考试数学被发现作弊,要记为0分,如何实现?
-
李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
-
后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
============================================
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
1
2df2 = df.copy()
1
2
3# values不能直接赋值. df2.values = np.random.randint(0, 150, size=(4,5))
1
2df2.values
1
2
3df2 = DataFrame(data=np.random.randint(0, 150, size=(4,5)), index=df.index, columns=df.columns) df2
1
2df
1
2(df + df2) / 2
1
2
3
4
5
6
7--------------------------------------------------------------------------- NameError Traceback (most recent call last) C:UsersADMINI~1AppDataLocalTemp/ipykernel_7776/3808069166.py in <module> ----> 1 (df + df2) / 2 NameError: name 'df' is not defined
1
2df.loc['张三', '数学'] = 0
1
2df
1
2df.loc['李四'] += 100
1
2df
1
2df + 10
处理丢失数据
1
2
3
4
5import numpy as np import pandas as pd
有两种丢失数据:
- None
- np.nan(NaN)
1
2None
1. None
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
1
2type(None)
1
2NoneType
1
2
3n = np.array([1,1,2,3, None]) n
1
2array([1, 1, 2, 3, None], dtype=object)
1
2n.sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-20b8964b5fcc> in <module> ----> 1 n.sum() d:1903.venvlibsite-packagesnumpycore_methods.py in _sum(a, axis, dtype, out, keepdims, initial, where) 36 def _sum(a, axis=None, dtype=None, out=None, keepdims=False, 37 initial=_NoValue, where=True): ---> 38 return umr_sum(a, axis, dtype, out, keepdims, initial, where) 39 40 def _prod(a, axis=None, dtype=None, out=None, keepdims=False, TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
object类型的运算要比int类型的运算慢得多
计算不同数据类型求和时间
%timeit np.arange(1e5,dtype=xxx).sum()
1
2
3%timeit np.arange(1e5, dtype=np.int32).sum()
1
2253 µs ± 30.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1
2
3%timeit np.arange(1e5, dtype=np.float64).sum()
1
2270 µs ± 24.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1
2
3%timeit np.arange(1e5, dtype=np.object).sum()
1
210.4 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
2. np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
1
2type(np.nan)
1
2float
1
2
3n = np.array([1,1,2,3, np.nan]) n.sum()
1
2nan
但可以使用np.nan*()函数来计算nan,此时视nan为0。
1
2np.nansum(n)
1
27.0
3. pandas中的None与NaN
1) pandas中None与np.nan都视作np.nan
1
2from pandas import Series, DataFrame
1
2
3
4
5
6data = np.random.randint(0,150, size=(4,4)) index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语','python'] df = DataFrame(data=data, index=index, columns=columns) df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 105 | 149 | 70 | 32 |
李四 | 118 | 44 | 117 | 24 |
王五 | 90 | 111 | 120 | 8 |
赵六 | 82 | 53 | 5 | 22 |
1
2df.loc['张三', '语文'] = None
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | 118.0 | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
使用DataFrame行索引与列索引修改DataFrame数据
1
2df.loc['李四', '语文'] = np.nan
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | NaN | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
1
2df.loc['张三', 'python'] = np.nan
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
2) pandas中None与np.nan的操作
- isnull():判断是否有NaN
- notnull():判断是否没有NaN
- dropna():过滤丢失数据
- fillna():填充丢失数据
(1)判断函数
- isnull()
- notnull()
1
2pd.isnull(df)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | True | False | False | True |
李四 | True | False | False | False |
王五 | False | False | False | False |
赵六 | False | False | False | False |
1
2pd.notnull(df)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | False | True | True | False |
李四 | False | True | True | True |
王五 | True | True | True | True |
赵六 | True | True | True | True |
1
2df.isnull()
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | True | False | False | True |
李四 | True | False | False | False |
王五 | False | False | False | False |
赵六 | False | False | False | False |
1
2
3
4# 和any结合使用,判断行或列是否存在NaN数据 # 默认axis=0,判断每一列是否有NaN数据 df.isnull().any(axis=0)
1
2
3
4
5
6
7
8
9
10语文 True 数学 False 英语 False python True dtype: bool
1
2
3# 检测每一行是否有NaN df.isnull().any(axis=1)
1
2
3
4
5
6
7
8
9
10张三 True 李四 True 王五 False 赵六 False dtype: bool
(2) 过滤函数
- dropna()
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | NaN | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
1
2
3
4# axis=1,删除列 # how='all'表示全部都是NaN才删除 df.dropna(axis=0, how='all')
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | NaN | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
1
2df.dropna(axis=0, how='any', inplace=True)
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
王五 | 64.0 | 47 | 97 | 148.0 |
赵六 | 125.0 | 75 | 113 | 97.0 |
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
1
2df.dropna(axis=0, how='any',subset=['语文', '数学', '英语'])
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
可以选择过滤的是行还是列(默认为行)
也可以选择过滤的方式 how = ‘all’
(3) 填充函数 Series/DataFrame
- fillna()
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
1
2
3# 用指定的值去填充 df.fillna(value=100)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 100.0 | 131 | 94 | 100.0 |
李四 | 100.0 | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
1
2
3
4# 使用已有的数据来填充 # 'backfill', 'bfill', 'pad', 'ffill' df.fillna(axis=0, method='bfill', limit=1)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | 124.0 |
李四 | 54.0 | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
1
2df.fillna(axis=1, method='bfill', inplace=True)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) C:UsersADMINI~1AppDataLocalTemp/ipykernel_7776/2566829753.py in <module> ----> 1 df.fillna(axis=1, method='bfill', inplace=True) c:usersadministratorappdatalocalprogramspythonpython39libsite-packagespandasutil_decorators.py in wrapper(*args, **kwargs) 309 stacklevel=stacklevel, 310 ) --> 311 return func(*args, **kwargs) 312 313 return wrapper c:usersadministratorappdatalocalprogramspythonpython39libsite-packagespandascoreframe.py in fillna(self, value, method, axis, inplace, limit, downcast) 5174 downcast=None, 5175 ) -> DataFrame | None: -> 5176 return super().fillna( 5177 value=value, 5178 method=method, c:usersadministratorappdatalocalprogramspythonpython39libsite-packagespandascoregeneric.py in fillna(self, value, method, axis, inplace, limit, downcast) 6324 if not self._mgr.is_single_block and axis == 1: 6325 if inplace: -> 6326 raise NotImplementedError() 6327 result = self.T.fillna(method=method, limit=limit).T 6328 NotImplementedError:
可以选择前向填充还是后向填充
对于DataFrame来说,还要选择填充的轴axis。记住,对于DataFrame来说:
- axis=0:index/行
- axis=1:columns/列
============================================
练习7:
-
简述None与NaN的区别
-
假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3
-
老师决定根据用数学的分数填充张三的英语成绩,如何实现?
用李四的英语成绩填充张三的英语成绩?
============================================
1
2
31, None 是python的object,不能参与计算,np.nan是float类型,可以参与计算,但是结果总是nan, 可以使用 np.nan*来计算正确的 值. 在pandas中,None和np.nan都被当成np.nan来处理.
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149 | 139 | 46 | 74 |
李四 | 33 | 32 | 119 | 116 |
王五 | 33 | 113 | 148 | 55 |
赵六 | 131 | 11 | 82 | 127 |
1
2df.loc['张三', '英语'] = np.nan
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149 | 139 | NaN | 74 |
李四 | 33 | 32 | 119.0 | 116 |
王五 | 33 | 113 | 148.0 | 55 |
赵六 | 131 | 11 | 82.0 | 127 |
1
2df.fillna(axis=1, method='pad')
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149.0 | 139.0 | 139.0 | 74.0 |
李四 | 33.0 | 32.0 | 119.0 | 116.0 |
王五 | 33.0 | 113.0 | 148.0 | 55.0 |
赵六 | 131.0 | 11.0 | 82.0 | 127.0 |
1
2df.fillna(axis=0, method='bfill', inplace=True)
1
2df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149 | 139 | 119.0 | 74 |
李四 | 33 | 32 | 119.0 | 116 |
王五 | 33 | 113 | 148.0 | 55 |
赵六 | 131 | 11 | 82.0 | 127 |
最后
以上就是爱笑心锁最近收集整理的关于pandas数据分析给力教程【完整版】(一)Pandas的数据结构的全部内容,更多相关pandas数据分析给力教程【完整版】(一)Pandas内容请搜索靠谱客的其他文章。
发表评论 取消回复