我是靠谱客的博主 爱笑心锁,这篇文章主要介绍pandas数据分析给力教程【完整版】(一)Pandas的数据结构,现在分享给大家,希望可以做个参考。

Pandas的数据结构

numpy 给力教程
下一篇:pandas数据分析给力教程【完整版】(二)

导入pandas

复制代码
1
2
from pandas import Series

1、Series

Series是一种类似于一维数组的对象,由下面两个部分组成:

  • values:一组数据(ndarray类型)
  • index:相关的数据索引标签

1)Series的创建

两种创建方式:

(1) 由列表或numpy数组创建,默认索引为0到N-1的整数型索引

由列表创建

复制代码
1
2
3
4
l = [1,2,3,4,5] s = Series(l, index=list('abcde')) s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
a 1 b 2 c 3 d 4 e 5 dtype: int64
复制代码
1
2
s.index
复制代码
1
2
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
复制代码
1
2
s.values
复制代码
1
2
array([1, 2, 3, 4, 5], dtype=int64)

还可以通过设置index参数指定索引

复制代码
1
2
3
s.index = [1,2,3,4,5] s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
1 1 2 2 3 3 4 4 5 5 dtype: int64
复制代码
1
2
3
s[1] = 10 s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
1 10 2 2 3 3 4 4 5 5 dtype: int64
复制代码
1
2
3
4
n = 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
22
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int32
复制代码
1
2
3
s[0] = 8 s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0 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
10
a 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
5
data = [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
2
s
复制代码
1
2
3
# 不推荐 s['a']
复制代码
1
2
1
复制代码
1
2
3
#推荐的写法 s.loc['a']
复制代码
1
2
1
复制代码
1
2
3
s.loc['a': 'c'] # 注意: 区间 是全闭区间
复制代码
1
2
3
4
5
6
7
8
a 1 b 2 c 3 dtype: int64
复制代码
1
2
s['a': 'c']
复制代码
1
2
3
4
5
6
7
8
a 1 b 2 c 3 dtype: int64

(2) 隐式索引:

  • 使用整数作为索引值
  • 使用.iloc[](推荐)

注意,此时是半开区间

复制代码
1
2
s
复制代码
1
2
3
4
5
6
7
8
9
10
a 1 b 2 c 3 d 4 dtype: int64
复制代码
1
2
s[0]
复制代码
1
2
1
复制代码
1
2
3
s = 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
22
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int32
复制代码
1
2
3
s.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
22
1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 dtype: int32
复制代码
1
2
s[1]
复制代码
1
2
0
复制代码
1
2
3
# 隐式索引的推荐写法 s.iloc[0]
复制代码
1
2
0
复制代码
1
2
s.iloc[0:3] # 隐式索引的切片是左闭右开的.
复制代码
1
2
3
4
5
6
7
8
1 0 2 1 3 2 dtype: int32

============================================

练习2:

使用多种方法对练习1创建的Series s1进行索引和切片:

索引:
数学 150

切片:
语文 150
数学 150
英语 150

============================================

复制代码
1
2
s1
复制代码
1
2
s1.loc['数学']
复制代码
1
2
s1.iloc[1]
复制代码
1
2
s1.loc[['数学']] # 再套一层中括号,返回原来的数据类型
复制代码
1
2
s1.loc[['数学', '理综']]
复制代码
1
2
s1.iloc[[1, 3]]
复制代码
1
2
s1.loc['语文': '英语']
复制代码
1
2
s1.iloc[0: 3]

3)Series的基本概念

可以把Series看成一个定长的有序字典

可以通过shape,size,index,values等得到series的属性

复制代码
1
2
s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 dtype: int32
复制代码
1
2
s.shape
复制代码
1
2
s.size
复制代码
1
2
s.index
复制代码
1
2
s.values

可以通过head(),tail()快速查看Series对象的样式

复制代码
1
2
s.head(3)
复制代码
1
2
3
4
5
6
7
8
1 0 2 1 3 2 dtype: int32
复制代码
1
2
s.tail(4)
复制代码
1
2
3
4
5
6
7
8
9
10
7 6 8 7 9 8 10 9 dtype: int32

当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况

复制代码
1
2
s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1 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
2
s.loc[0] = np.nan
复制代码
1
2
s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1 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
2
pd.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
24
1 False 2 False 3 False 4 False 5 False 6 False 7 False 8 False 9 False 10 False 0 True dtype: bool
复制代码
1
2
pd.notnull(s)
复制代码
1
2
s.isnull()
复制代码
1
2
s.notnull()

Series对象本身及其实例都有一个name属性

复制代码
1
2
3
s.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
24
1 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
3
Series.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
24
1 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
2
s + 1

(2) Series之间的运算

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
复制代码
1
2
s
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1 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
3
s2 = 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
24
3 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
3
s + 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
30
0 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
30
0 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:

  1. 想一想Series运算和ndarray运算的规则有什么不同?

  2. 新建另一个索引包含“文综”的Series s2,并与s1进行多种算术操作。思考如何保存所有数据。

============================================

ndarray有广播机制,Series没有广播机制,Series只是根据相同的索引进行运算

复制代码
1
2
3
s2 = Series({'语文': 108, '数学': 149, '英语': 138, '文综': 268}) s2
复制代码
1
2
3
4
5
6
7
8
9
10
语文 108 数学 149 英语 138 文综 268 dtype: int64
复制代码
1
2
s2.sum()
复制代码
1
2
663
复制代码
1
2
3
s1 + s2
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
数学 299.0 文综 NaN 理综 NaN 英语 288.0 语文 258.0 dtype: float64
复制代码
1
2
s1.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
3
from pandas import DataFrame

分块创建

复制代码
1
2
3
4
5
6
data = np.random.randint(0,150, size=(4,4)) index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语','python'] df = DataFrame(data=data, index=index, columns=columns) df
语文数学英语python
张三104263852
李四111048841
王五3811936139
赵六679321130

使用字典创建

复制代码
1
2
3
4
df = 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
张三3011014389
李四1168553138
王五283229141
赵六91235050

DataFrame属性:values、columns、index、shape

复制代码
1
2
df.values
复制代码
1
2
df.columns
复制代码
1
2
df.index
复制代码
1
2
df.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
6
data = [[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
2
df
语文数学英语python
张三118125312
李四48348154
王五325880133
赵六107252542
复制代码
1
2
df['语文']
复制代码
1
2
3
4
5
6
7
8
9
10
张三 118 李四 48 王五 32 赵六 107 Name: 语文, dtype: int32
复制代码
1
2
df.语文
复制代码
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计算机
张三118125312110
李四48348154131
王五325880133132
赵六107252542129
复制代码
1
2
3
# 新增一列的时候不能使用属性的写法 df.理综 = np.random.randint(0,150, size=4)
复制代码
1
2
3
C: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
2
df
语文数学英语python计算机
张三118125312110
李四48348154131
王五325880133132
赵六107252542129

(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
2
df.iloc[1]

(3) 对元素索引的方法

  • 使用列索引
  • 使用行索引(iloc[3,1]
  • 使用values属性(二维numpy数组)
复制代码
1
2
3
4
# 先列后行 # 链式索引的赋值,不要这么写 df['英语']['李四'] = 88
复制代码
1
2
df
复制代码
1
2
3
# 先行后列 df.loc['李四'].loc['英语']
复制代码
1
2
3
# 推荐写法 df.loc['李四', '英语']
复制代码
1
2
df.iloc[1, 2]

链式索引不推荐.

复制代码
1
2
df.loc[['李四']]
语文数学英语python计算机
李四48348154131

3)DataFrame切片

(1)列切片

复制代码
1
2
df['数学': 'python'] # 这样写不是对列切片
语文数学英语python
复制代码
1
2
df.loc[:, '数学': 'python']
数学英语python
张三125312
李四348154
王五5880133
赵六252542
复制代码
1
2
df.iloc[:, 1:3]
数学英语
张三110143
李四8553
王五3229
赵六2350
复制代码
1
2
df[['数学', '英语', 'python']]
数学英语python
张三11014389
李四8553138
王五3229141
赵六235050
复制代码
1
2
df.iloc[:, 0:3]
语文数学英语
张三30110143
李四1168553
王五283229
赵六912350

(2)行切片

复制代码
1
2
df['李四': '王五'] # 全闭的区间
语文数学英语python
李四1168553138
王五283229141

DataFrame 索引总结

1,行索引用.loc, 列索索引用中括号

2,对元素的索引,先索引行,再索引列. df.loc[index, columns]

3,如果还想返回DataFrame,那么使用两层中括号

注意:

  • 直接使用中括号的时候
    • 索引表示的是列索引
    • 切片表示的是行切片
  • 不要使用链式索引

============================================

练习5:

使用多种方法对ddd进行索引和切片,并比较其中的区别

============================================

复制代码
1
2
ddd
复制代码
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
2
ddd.loc[['语文'], ['张三']]
复制代码
1
2
ddd['语文': '数学']
复制代码
1
2
ddd.loc['语文': '数学']
复制代码
1
2
ddd.iloc[0:2]
复制代码
1
2
ddd.loc['英语', '李四'] = 108

4)DataFrame的运算

(1)DataFrame之间的运算

同Series一样:

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN

DataFrame和单个数字进行计算

复制代码
1
2
df
语文数学英语python
张三3011014389
李四1168553138
王五283229141
赵六91235050
复制代码
1
2
df + 1
语文数学英语python
张三3111114490
李四1178654139
王五293330142
赵六92245151

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
张三14238472
李四77384643
王五33784127
赵六142482480
复制代码
1
2
df
语文数学英语python
张三3011014389
李四1168553138
王五283229141
赵六91235050
复制代码
1
2
3
df2.loc['田七'] = np.random.randint(0,150, size=4) df2
语文数学英语python
张三75918188
李四133112881
王五13869250
赵六516423113
田七146582042
复制代码
1
2
df + df2
语文数学英语python
张三105.0201.0224.0177.0
李四249.086.0181.0219.0
王五41.0118.0121.0191.0
田七NaNNaNNaNNaN
赵六142.087.073.0163.0
复制代码
1
2
df.add(df2, fill_value=0)
语文数学英语python
张三105.0201.0224.0177.0
李四249.086.0181.0219.0
王五41.0118.0121.0191.0
田七146.058.020.042.0
赵六142.087.073.0163.0

下面是Python 操作符与pandas操作函数的对应表:

Python OperatorPandas Method(s)
+add()
-sub(), subtract()
*mul(), multiply()
/truediv(), div(), divide()
//floordiv()
%mod()
**pow()

(2) Series与DataFrame之间的运算

【重要】

  • 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。
  • 使用pandas操作函数:
    • axis=0:以列为单位操作(参数必须是列),对所有列都有效。
    • axis=1:以行为单位操作(参数必须是行),对所有行都有效。
复制代码
1
2
df
语文数学英语python
张三3011014389
李四1168553138
王五283229141
赵六91235050
复制代码
1
2
3
s = 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
2
df + s # 直接进行运算,观察DataFrame的列索引和Series的索引是否一致,一致就进行相应的运算
python数学英语计算机语文
张三171224233NaN170
李四220199143NaN256
王五223146119NaN168
赵六132137140NaN231
复制代码
1
2
3
s = 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
3
df + s # 使用运算符的默认操作是DataFrame的列索引和Series的列索引进行比较
python张三数学李四王五英语语文赵六
张三NaNNaNNaNNaNNaNNaNNaNNaN
李四NaNNaNNaNNaNNaNNaNNaNNaN
王五NaNNaNNaNNaNNaNNaNNaNNaN
赵六NaNNaNNaNNaNNaNNaNNaNNaN
复制代码
1
2
df.add(s, axis=0) # 使用axis改变运算的方向

归纳总结

1,DataFrame和单个数字运算,每个元素分别运算

2,DataFrame和DataFrame运算,相同的行列索引进行运算,不同索引补NaN

3,DataFrame和Series运算,使用运算符的时候,默认比较DataFrame的列索引和Series的索引

4,如果想保留原始数据,或者改变运算的方向,使用pandas封装的方法

============================================

练习6:

  1. 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。

  2. 假设张三期中考试数学被发现作弊,要记为0分,如何实现?

  3. 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?

  4. 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?

============================================

复制代码
1
2
df
语文数学英语python
张三3011014389
李四1168553138
王五283229141
赵六91235050
复制代码
1
2
df2 = df.copy()
复制代码
1
2
3
# values不能直接赋值. df2.values = np.random.randint(0, 150, size=(4,5))
复制代码
1
2
df2.values
复制代码
1
2
3
df2 = DataFrame(data=np.random.randint(0, 150, size=(4,5)), index=df.index, columns=df.columns) df2
复制代码
1
2
df
复制代码
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
2
df.loc['张三', '数学'] = 0
复制代码
1
2
df
复制代码
1
2
df.loc['李四'] += 100
复制代码
1
2
df
复制代码
1
2
df + 10

处理丢失数据

复制代码
1
2
3
4
5
import numpy as np import pandas as pd

有两种丢失数据:

  • None
  • np.nan(NaN)
复制代码
1
2
None

1. None

None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。

复制代码
1
2
type(None)
复制代码
1
2
NoneType
复制代码
1
2
3
n = np.array([1,1,2,3, None]) n
复制代码
1
2
array([1, 1, 2, 3, None], dtype=object)
复制代码
1
2
n.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
2
253 µ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
2
270 µ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
2
10.4 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

2. np.nan(NaN)

np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。

复制代码
1
2
type(np.nan)
复制代码
1
2
float
复制代码
1
2
3
n = np.array([1,1,2,3, np.nan]) n.sum()
复制代码
1
2
nan

但可以使用np.nan*()函数来计算nan,此时视nan为0。

复制代码
1
2
np.nansum(n)
复制代码
1
2
7.0

3. pandas中的None与NaN

1) pandas中None与np.nan都视作np.nan

复制代码
1
2
from pandas import Series, DataFrame
复制代码
1
2
3
4
5
6
data = np.random.randint(0,150, size=(4,4)) index = ['张三', '李四', '王五', '赵六'] columns = ['语文', '数学', '英语','python'] df = DataFrame(data=data, index=index, columns=columns) df
语文数学英语python
张三1051497032
李四1184411724
王五901111208
赵六8253522
复制代码
1
2
df.loc['张三', '语文'] = None
复制代码
1
2
df
语文数学英语python
张三NaN1497032
李四118.04411724
王五90.01111208
赵六82.053522

使用DataFrame行索引与列索引修改DataFrame数据

复制代码
1
2
df.loc['李四', '语文'] = np.nan
复制代码
1
2
df
语文数学英语python
张三NaN1497032
李四NaN4411724
王五90.01111208
赵六82.053522
复制代码
1
2
df.loc['张三', 'python'] = np.nan
复制代码
1
2
df
语文数学英语python
张三NaN13194NaN
李四NaN5108124.0
王五54.07436144.0
赵六33.01173437.0

2) pandas中None与np.nan的操作

  • isnull():判断是否有NaN
  • notnull():判断是否没有NaN
  • dropna():过滤丢失数据
  • fillna():填充丢失数据

(1)判断函数

  • isnull()
  • notnull()
复制代码
1
2
pd.isnull(df)
语文数学英语python
张三TrueFalseFalseTrue
李四TrueFalseFalseFalse
王五FalseFalseFalseFalse
赵六FalseFalseFalseFalse
复制代码
1
2
pd.notnull(df)
语文数学英语python
张三FalseTrueTrueFalse
李四FalseTrueTrueTrue
王五TrueTrueTrueTrue
赵六TrueTrueTrueTrue
复制代码
1
2
df.isnull()
语文数学英语python
张三TrueFalseFalseTrue
李四TrueFalseFalseFalse
王五FalseFalseFalseFalse
赵六FalseFalseFalseFalse
复制代码
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
2
df
语文数学英语python
张三NaN1497032
李四NaN4411724
王五90.01111208
赵六82.053522
复制代码
1
2
3
4
# axis=1,删除列 # how='all'表示全部都是NaN才删除 df.dropna(axis=0, how='all')
语文数学英语python
张三NaN1497032
李四NaN4411724
王五90.01111208
赵六82.053522
复制代码
1
2
df.dropna(axis=0, how='any', inplace=True)
复制代码
1
2
df
语文数学英语python
王五64.04797148.0
赵六125.07511397.0
复制代码
1
2
df
语文数学英语python
张三NaN13194NaN
李四NaN5108124.0
王五54.07436144.0
赵六33.01173437.0
复制代码
1
2
df.dropna(axis=0, how='any',subset=['语文', '数学', '英语'])
语文数学英语python
王五54.07436144.0
赵六33.01173437.0

可以选择过滤的是行还是列(默认为行)

也可以选择过滤的方式 how = ‘all’

(3) 填充函数 Series/DataFrame

  • fillna()
复制代码
1
2
df
语文数学英语python
张三NaN13194NaN
李四NaN5108124.0
王五54.07436144.0
赵六33.01173437.0
复制代码
1
2
3
# 用指定的值去填充 df.fillna(value=100)
语文数学英语python
张三100.013194100.0
李四100.05108124.0
王五54.07436144.0
赵六33.01173437.0
复制代码
1
2
df
语文数学英语python
张三NaN13194NaN
李四NaN5108124.0
王五54.07436144.0
赵六33.01173437.0
复制代码
1
2
3
4
# 使用已有的数据来填充 # 'backfill', 'bfill', 'pad', 'ffill' df.fillna(axis=0, method='bfill', limit=1)
语文数学英语python
张三NaN13194124.0
李四54.05108124.0
王五54.07436144.0
赵六33.01173437.0
复制代码
1
2
df.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:

  1. 简述None与NaN的区别

  2. 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3

  3. 老师决定根据用数学的分数填充张三的英语成绩,如何实现?
    用李四的英语成绩填充张三的英语成绩?

============================================

复制代码
1
2
3
1, None 是python的object,不能参与计算,np.nan是float类型,可以参与计算,但是结果总是nan, 可以使用 np.nan*来计算正确的 值. 在pandas中,None和np.nan都被当成np.nan来处理.
复制代码
1
2
df
语文数学英语python
张三1491394674
李四3332119116
王五3311314855
赵六1311182127
复制代码
1
2
df.loc['张三', '英语'] = np.nan
复制代码
1
2
df
语文数学英语python
张三149139NaN74
李四3332119.0116
王五33113148.055
赵六1311182.0127
复制代码
1
2
df.fillna(axis=1, method='pad')
语文数学英语python
张三149.0139.0139.074.0
李四33.032.0119.0116.0
王五33.0113.0148.055.0
赵六131.011.082.0127.0
复制代码
1
2
df.fillna(axis=0, method='bfill', inplace=True)
复制代码
1
2
df
语文数学英语python
张三149139119.074
李四3332119.0116
王五33113148.055
赵六1311182.0127

最后

以上就是爱笑心锁最近收集整理的关于pandas数据分析给力教程【完整版】(一)Pandas的数据结构的全部内容,更多相关pandas数据分析给力教程【完整版】(一)Pandas内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部