概述
Pandas的数据结构
numpy 给力教程
下一篇:pandas数据分析给力教程【完整版】(二)
导入pandas
from pandas import Series
1、Series
Series是一种类似于一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
1)Series的创建
两种创建方式:
(1) 由列表或numpy数组创建,默认索引为0到N-1的整数型索引
由列表创建
l = [1,2,3,4,5]
s = Series(l, index=list('abcde'))
s
a
1
b
2
c
3
d
4
e
5
dtype: int64
s.index
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
s.values
array([1, 2, 3, 4, 5], dtype=int64)
还可以通过设置index参数指定索引
s.index = [1,2,3,4,5]
s
1
1
2
2
3
3
4
4
5
5
dtype: int64
s[1] = 10
s
1
10
2
2
3
3
4
4
5
5
dtype: int64
n = np.arange(0,10)
s = Series(n.copy())
s
0
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
dtype: int32
s[0] = 8
s
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) 由字典创建
# 字典的key对应Series的索引
s = Series({'a':1, 'b':2, 'c':3, 'd': 4})
s
a
1
b
2
c
3
d
4
dtype: int64
============================================
练习1:
使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300
============================================
# 字典
s1 = Series({'语文': 150, '数学': 150, '英语': 150, '理综': 300})
s1
data = [150, 150, 150, 300]
index = ['语文', '数学', '英语', '理综']
s1 = Series(data=data,index=index)
s1
语文
150
数学
150
英语
150
理综
300
dtype: int64
2)Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的是一个Series类型)。索引分为显示索引和隐式索引:
(1) 显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
注意,此时是闭区间
s
# 不推荐
s['a']
1
#推荐的写法
s.loc['a']
1
s.loc['a': 'c']
# 注意: 区间 是全闭区间
a
1
b
2
c
3
dtype: int64
s['a': 'c']
a
1
b
2
c
3
dtype: int64
(2) 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐)
注意,此时是半开区间
s
a
1
b
2
c
3
d
4
dtype: int64
s[0]
1
s = Series(np.arange(10))
s
0
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
dtype: int32
s.index = np.arange(1,11)
s
1
0
2
1
3
2
4
3
5
4
6
5
7
6
8
7
9
8
10
9
dtype: int32
s[1]
0
# 隐式索引的推荐写法
s.iloc[0]
0
s.iloc[0:3] # 隐式索引的切片是左闭右开的.
1
0
2
1
3
2
dtype: int32
============================================
练习2:
使用多种方法对练习1创建的Series s1进行索引和切片:
索引:
数学 150
切片:
语文 150
数学 150
英语 150
============================================
s1
s1.loc['数学']
s1.iloc[1]
s1.loc[['数学']] # 再套一层中括号,返回原来的数据类型
s1.loc[['数学', '理综']]
s1.iloc[[1, 3]]
s1.loc['语文': '英语']
s1.iloc[0: 3]
3)Series的基本概念
可以把Series看成一个定长的有序字典
可以通过shape,size,index,values等得到series的属性
s
1
0
2
1
3
2
4
3
5
4
6
5
7
6
8
7
9
8
10
9
dtype: int32
s.shape
s.size
s.index
s.values
可以通过head(),tail()快速查看Series对象的样式
s.head(3)
1
0
2
1
3
2
dtype: int32
s.tail(4)
7
6
8
7
9
8
10
9
dtype: int32
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
s
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
s.loc[0] = np.nan
s
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()函数检测缺失数据
pd.isnull(s)
1
False
2
False
3
False
4
False
5
False
6
False
7
False
8
False
9
False
10
False
0
True
dtype: bool
pd.notnull(s)
s.isnull()
s.notnull()
Series对象本身及其实例都有一个name属性
s.name = 'Series s'
s
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
Series.name = 'Name'
s
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
s + 1
(2) Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
s
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
s2 = Series(np.random.randint(0, 10, size=11), index=np.arange(3, 14))
s2
3
0
4
5
5
3
6
9
7
1
8
9
9
1
10
7
11
9
12
6
13
1
dtype: int32
s + s2
# 相同的索引进行运算,不同的索引补NaN
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()函数
# 使用pandas封装的运算函数,保留所有index对应value
s.add(s2, fill_value=0)
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:
-
想一想Series运算和ndarray运算的规则有什么不同?
-
新建另一个索引包含“文综”的Series s2,并与s1进行多种算术操作。思考如何保存所有数据。
============================================
ndarray有广播机制,Series没有广播机制,Series只是根据相同的索引进行运算
s2 = Series({'语文': 108, '数学': 149, '英语': 138, '文综': 268})
s2
语文
108
数学
149
英语
138
文综
268
dtype: int64
s2.sum()
663
s1
+ s2
数学
299.0
文综
NaN
理综
NaN
英语
288.0
语文
258.0
dtype: float64
s1.add(s2, fill_value=0) / 2
数学
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。
from
pandas import DataFrame
分块创建
data = 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 |
使用字典创建
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 | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
DataFrame属性:values、columns、index、shape
df.values
df.columns
df.index
df.shape
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为ddd:
张三
李四
语文 150
0
数学 150
0
英语 150
0
理综 300
0
============================================
# 字典
ddd = DataFrame({'张三': [150]*
3 + [300], '李四': [0]* 4})
ddd.index = ['语文', '数学', '英语', '理综']
ddd
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属性也已经设置好了,就是相应的列名。
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 118 | 12 | 53 | 12 |
李四 | 48 | 34 | 81 | 54 |
王五 | 32 | 58 | 80 | 133 |
赵六 | 107 | 25 | 25 | 42 |
df['语文']
张三
118
李四
48
王五
32
赵六
107
Name: 语文, dtype: int32
df.语文
张三
118
李四
48
王五
32
赵六
107
Name: 语文, dtype: int32
# 新增一列
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 |
# 新增一列的时候不能使用属性的写法
df.理综 = np.random.randint(0,150, size=4)
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)
df
语文 | 数学 | 英语 | 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。
# 显式写法
df.loc['张三']
语文
118
数学
12
英语
53
python
12
计算机
110
Name: 张三, dtype: int32
df.iloc[1]
(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]
- 使用values属性(二维numpy数组)
# 先列后行
# 链式索引的赋值,不要这么写
df['英语']['李四'] = 88
df
# 先行后列
df.loc['李四'].loc['英语']
# 推荐写法
df.loc['李四', '英语']
df.iloc[1, 2]
链式索引不推荐.
df.loc[['李四']]
语文 | 数学 | 英语 | python | 计算机 | |
---|---|---|---|---|---|
李四 | 48 | 34 | 81 | 54 | 131 |
3)DataFrame切片
(1)列切片
df['数学': 'python'] # 这样写不是对列切片
语文 | 数学 | 英语 | python |
---|
df.loc[:, '数学': 'python']
数学 | 英语 | python | |
---|---|---|---|
张三 | 12 | 53 | 12 |
李四 | 34 | 81 | 54 |
王五 | 58 | 80 | 133 |
赵六 | 25 | 25 | 42 |
df.iloc[:, 1:3]
数学 | 英语 | |
---|---|---|
张三 | 110 | 143 |
李四 | 85 | 53 |
王五 | 32 | 29 |
赵六 | 23 | 50 |
df[['数学', '英语', 'python']]
数学 | 英语 | python | |
---|---|---|---|
张三 | 110 | 143 | 89 |
李四 | 85 | 53 | 138 |
王五 | 32 | 29 | 141 |
赵六 | 23 | 50 | 50 |
df.iloc[:, 0:3]
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 30 | 110 | 143 |
李四 | 116 | 85 | 53 |
王五 | 28 | 32 | 29 |
赵六 | 91 | 23 | 50 |
(2)行切片
df['李四': '王五'] # 全闭的区间
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
DataFrame 索引总结
1,行索引用.loc, 列索索引用中括号
2,对元素的索引,先索引行,再索引列. df.loc[index, columns]
3,如果还想返回DataFrame,那么使用两层中括号
注意:
- 直接使用中括号的时候
- 索引表示的是列索引
- 切片表示的是行切片
- 不要使用链式索引
============================================
练习5:
使用多种方法对ddd进行索引和切片,并比较其中的区别
============================================
ddd
---------------------------------------------------------------------------
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
ddd.loc[['语文'], ['张三']]
ddd['语文': '数学']
ddd.loc['语文': '数学']
ddd.iloc[0:2]
ddd.loc['英语', '李四'] = 108
4)DataFrame的运算
(1)DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
DataFrame和单个数字进行计算
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
df + 1
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 31 | 111 | 144 | 90 |
李四 | 117 | 86 | 54 | 139 |
王五 | 29 | 33 | 30 | 142 |
赵六 | 92 | 24 | 51 | 51 |
DataFrame和DataFrame进行计算
# 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 |
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
df2.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 |
df + 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 |
df.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:以行为单位操作(参数必须是行),对所有行都有效。
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
s = Series(data=np.random.randint(0,150,size=5), index=['语文', '数学', '英语', 'python', '计算机'])
s
语文
140
数学
114
英语
90
python
82
计算机
9
dtype: int32
df + s # 直接进行运算,观察DataFrame的列索引和Series的索引是否一致,一致就进行相应的运算
python | 数学 | 英语 | 计算机 | 语文 | |
---|---|---|---|---|---|
张三 | 171 | 224 | 233 | NaN | 170 |
李四 | 220 | 199 | 143 | NaN | 256 |
王五 | 223 | 146 | 119 | NaN | 168 |
赵六 | 132 | 137 | 140 | NaN | 231 |
s = Series(data=np.random.randint(0,150,size=4), index=['张三', '李四', '王五', '赵六'])
s
张三
122
李四
109
王五
84
赵六
45
dtype: int32
df + 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 |
df.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分,如何实现?
============================================
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 30 | 110 | 143 | 89 |
李四 | 116 | 85 | 53 | 138 |
王五 | 28 | 32 | 29 | 141 |
赵六 | 91 | 23 | 50 | 50 |
df2 = df.copy()
# values不能直接赋值.
df2.values = np.random.randint(0, 150, size=(4,5))
df2.values
df2 = DataFrame(data=np.random.randint(0, 150, size=(4,5)), index=df.index, columns=df.columns)
df2
df
(df + df2) / 2
---------------------------------------------------------------------------
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
df.loc['张三', '数学'] = 0
df
df.loc['李四'] += 100
df
df + 10
处理丢失数据
import numpy as np
import pandas
as
pd
有两种丢失数据:
- None
- np.nan(NaN)
None
1. None
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
type(None)
NoneType
n = np.array([1,1,2,3, None])
n
array([1, 1, 2, 3, None], dtype=object)
n.sum()
---------------------------------------------------------------------------
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()
%timeit
np.arange(1e5, dtype=np.int32).sum()
253 µs ± 30.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit
np.arange(1e5, dtype=np.float64).sum()
270 µs ± 24.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit
np.arange(1e5, dtype=np.object).sum()
10.4 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
2. np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
type(np.nan)
float
n = np.array([1,1,2,3, np.nan])
n.sum()
nan
但可以使用np.nan*()函数来计算nan,此时视nan为0。
np.nansum(n)
7.0
3. pandas中的None与NaN
1) pandas中None与np.nan都视作np.nan
from pandas import Series, DataFrame
data = 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 |
df.loc['张三', '语文'] = None
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | 118.0 | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
使用DataFrame行索引与列索引修改DataFrame数据
df.loc['李四', '语文'] = np.nan
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | NaN | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
df.loc['张三', 'python'] = np.nan
df
语文 | 数学 | 英语 | 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()
pd.isnull(df)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | True | False | False | True |
李四 | True | False | False | False |
王五 | False | False | False | False |
赵六 | False | False | False | False |
pd.notnull(df)
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | False | True | True | False |
李四 | False | True | True | True |
王五 | True | True | True | True |
赵六 | True | True | True | True |
df.isnull()
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | True | False | False | True |
李四 | True | False | False | False |
王五 | False | False | False | False |
赵六 | False | False | False | False |
# 和any结合使用,判断行或列是否存在NaN数据
# 默认axis=0,判断每一列是否有NaN数据
df.isnull().any(axis=0)
语文
True
数学
False
英语
False
python
True
dtype: bool
# 检测每一行是否有NaN
df.isnull().any(axis=1)
张三
True
李四
True
王五
False
赵六
False
dtype: bool
(2) 过滤函数
- dropna()
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 149 | 70 | 32 |
李四 | NaN | 44 | 117 | 24 |
王五 | 90.0 | 111 | 120 | 8 |
赵六 | 82.0 | 53 | 5 | 22 |
# 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 |
df.dropna(axis=0, how='any', inplace=True)
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
王五 | 64.0 | 47 | 97 | 148.0 |
赵六 | 125.0 | 75 | 113 | 97.0 |
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
df.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()
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
# 用指定的值去填充
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 |
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | NaN | 131 | 94 | NaN |
李四 | NaN | 5 | 108 | 124.0 |
王五 | 54.0 | 74 | 36 | 144.0 |
赵六 | 33.0 | 117 | 34 | 37.0 |
# 使用已有的数据来填充
# '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 |
df.fillna(axis=1, method='bfill', inplace=True)
---------------------------------------------------------------------------
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, None 是python的object,不能参与计算,np.nan是float类型,可以参与计算,但是结果总是nan, 可以使用 np.nan*来计算正确的 值.
在pandas中,None和np.nan都被当成np.nan来处理.
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149 | 139 | 46 | 74 |
李四 | 33 | 32 | 119 | 116 |
王五 | 33 | 113 | 148 | 55 |
赵六 | 131 | 11 | 82 | 127 |
df.loc['张三', '英语'] = np.nan
df
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 149 | 139 | NaN | 74 |
李四 | 33 | 32 | 119.0 | 116 |
王五 | 33 | 113 | 148.0 | 55 |
赵六 | 131 | 11 | 82.0 | 127 |
df.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 |
df.fillna(axis=0, method='bfill', inplace=True)
df
语文 | 数学 | 英语 | 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的数据结构所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复