Pandas基本操作(简单series和dataframe)

Pandas基本操作(简单series和dataframe)

本文章说明介绍series和dataframe两种数据类型基本的简单操作,后续更新多重操作

一、什么是pandas

1. 简介

1)Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的;

2)pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具;

3)pandas提供了大量能使我们快速便捷地处理数据的函数和方法;

4)它是使Python成为强大而高效的数据分析环境的重要因素之一。

2. 数据结构

Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近。Series如今能保存不同种数据类型,字符串、boolean值、数字等都能保存在Series中。

Time- Series:以时间为索引的Series。

DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。

Panel :三维的数组,可以理解为DataFrame的容器。

二、Series

1. 什么是Series

Series是一种类似于一维数组的对象,能够保存任何数据类型(整数,字符串,浮点数,Python对象等),由下面两个部分组成:

values:一组数据(ndarray类型)

index:相关的数据索引标签

Series(
    data=None,
    index=None,
    dtype=None,
    name=None,
    copy=False,
    fastpath=False,
)
参数说明:
data:数据,可以是数组、可迭代对象、字典或者包含顺序存储的数据;当为字典时,如果不再指定index,则key为index,value为data
index:与data具有相同长度的索引值;不唯一;如果不提供,默认为RangeIndex (0, 1, 2, ..., n);如果同时使用index和字典,将会覆盖字典的keys
dtype:输出的元素类型,如果不指定,与的data一致
name:给输出的Series指定一个name名称属性
2. Series的创建
from pandas import Series
2.1 由列表或numpy数组创建
1.特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
2.由列表创建series,创建的是副本(深拷贝)
# 由列表创建series
l = [1,2,3,4,5]
s = Series(l)
s[0] =  20
s
>>0    20
1     2
2     3
3     4
4     5
dtype: int64
# 由numpy创建
n = np.array([1,2,3,4,5])
s = Series(n, )
s.index=list('ABCDE')#还可以通过设置index参数指定索引
s
>>A    1
B    2
C    3
D    4
E    5
dtype: int32
2.2 由字典创建
data_dict = {'A': 1, 'B': 2, 'C': 3, 'D':4}
s = Series(data_dict)
s
>>A    1
B    2
C    3
D    4
dtype: int64
3. Series的索引和切片

可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:

3.1 显式索引
#Series操作实例
data = np.random.randint(0,10, size=10)
index = list('abcdefghij')
s = Series(data=data, index=index)
s
>>a    6
b    6
c    7
d    4
e    6
f    3
g    8
h    1
i    6
j    6
dtype: int32
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
#第一种,直接写中括号
s['d']
>>4
# 第二种,使用loc[], location 推荐写法.
s.loc['d']
>>4
3.2 隐式索引
- 使用整数作为索引值
- 使用.iloc[](推荐)
s.iloc[3]
>>4
s[3]
>>4
3.3 对比总结
s.index = np.arange(0,10)#修改s的索引
s
>>0    6
1    6
2    7
3    4
4    6
5    3
6    8
7    1
8    6
9    6
dtype: int32

在这种情况下,使用s[]没有办法再去区分显式索引隐式索引

故:1)在Series中,永远不要使用直接中括号进行索引.

2)推荐显式索引用.loc[], 隐式索引用.iloc[]

3.4 切片

在3.3的基础上

#显式切片,全闭区间,左右都可以取到
s.loc[1:5]
>>1    6
2    7
3    4
4    6
5    3
dtype: int32
# 隐式索引的切片 左闭右开.
s.iloc[1:5]
>>1    6
2    7
3    4
4    6
dtype: int32
3.5 练习
============================================

练习2:

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

找到数学对应的成绩

索引: 数学 150

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

============================================
data = [150,150,150, 300]
index = ['语文', '数学', '英语', '理综']
s1 = Series(data=data, index=index)
s1
>>语文    150
数学    150
英语    150
理综    300
dtype: int64
#找到数学对应的成绩(获取的是一个值)
#显式
s1.loc['数学']
#隐式
s1.iloc[1]
>>150
#索引: 数学 150(获取的是Series)
# 索引的时候,再套一层总括还,那么还会返回原来数据类型
#显式
s1.loc[['数学']]
#隐式
s1.iloc[[1]]
>>数学    150
dtype: int64
#切片: 语文 150 数学 150 英语 150
#显式
s1.loc['语文':'英语']
#隐式
s1.iloc[:3]
>>语文    150
数学    150
英语    150
dtype: int64
4. Series的属性

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

4.1 属性

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

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

以3.5中的s1为例

s1.shape#元组形式返回基础数据的形状
>>(4,)
s1.size#返回基础数据的数量
>>4
s1.index
>>Index(['语文', '数学', '英语', '理综'], dtype='object')
s1.values
>>array([150, 150, 150, 300], dtype=int64)
s = Series({'a': np.nan, 'b': 1, 'c': 2, 'd': 3}, name='test')
s
>>a    NaN
b    1.0
c    2.0
d    3.0
Name: test, dtype: float64
4.2 样式快速查看

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

#head():默认返回前5个,也可给定具体的数目
s.head(2)
>>1    9
2    9
dtype: int32

tile():默认返回后5个,也可给定具体的数目

4.3 缺失数据显示NaN(not a number)

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

s = Series({'a': np.nan, 'b': 1, 'c': 2, 'd': 3})
s
>>a    NaN
b    1.0
c    2.0
d    3.0
dtype: float64

可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据

pd.isnull(s)
>>a     True
b    False
c    False
d    False
dtype: bool

pd.notnull(s)
>>a    False
b     True
c     True
d     True
dtype: bool
s.isnull()
>>a     True
b    False
c    False
d    False
dtype: bool
s.notnull()
>>a    False
b     True
c     True
d     True
dtype: bool
5. Series的计算
5.1 与数进行运算

适用于numpy的数组运算也适用于Series

s + 1
a    NaN #与数进行运算为NaN
b    2.0
c    3.0
d    4.0
dtype: float64
data = [150,150,150, 300]
index = ['语文', '数学', '英语', '理综']
s1 = Series(data=data, index=index)
s1
>>语文    150
数学    150
英语    150
理综    300
dtype: int64
s1 + 1 # Series和单个数字运算,每个元素分别和这个数字运算.
>>语文    151
数学    151
英语    151
理综    301
Name: Series, dtype: int64
5.2 Series之间进行运算

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

Series和Series之间的运算根据索引进行运算,相同的索引才会进行运算,索引不同,补NaN.
要想保留所有的value,则需要使用.add()函数,s.add(ss, fill_value=0),使得fill_value=0
#索引相同,对应的位置数据进行运算(+-*/一样)
s = Series({'a':1, 'b':2, 'c': 3})
ss = Series({'a':1, 'b':2, 'c': 3})
display(s,ss)
>>a    1
b    2
c    3
dtype: int64
a    1
b    2
c    3
dtype: int64
s + ss
>>a    2
b    4
c    6
dtype: int64
#索引不同,补NaN,相同的索引计算同上(+-*/一样)
s = Series({'a':1, 'b':2, 'c': 3})
ss = Series({ 'b':2, 'c': 3, 'd':4})
display(s,ss)
>>a    1
b    2
c    3
dtype: int64
b    2
c    3
d    4
dtype: int64
    
s + ss
>>a    NaN
b    4.0
c    6.0
d    NaN
dtype: float64
    
s / ss
>>a    NaN
b    1.0
c    1.0
d    NaN
dtype: float64
5.2 练习
============================================

练习3:

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

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

============================================
1)ndarray有广播机制,Series没有广播机制;
2)Series根据相同的索引进行运算,索引不同补NaN,ndarry进行广播,广播失败则报错
data = [150,150,150, 300]
index = ['语文', '数学', '英语', '理综']
s1 = Series(data=data, index=index)
s1
>>语文    150
数学    150
英语    150
理综    300
dtype: int64

s2 = Series({'语文': 150, '数学': 150, '英语': 150, '文综':  300})
s2
>>语文    150
数学    150
英语    150
文综    300
dtype: int64

s1+s2
数学    300.0
文综      NaN
理综      NaN
英语    300.0
语文    300.0
dtype: float64

s1.add(s2, fill_value=0)#索引不同,不存在的一方默认该值为0
数学    300.0
文综    300.0
理综    300.0
英语    300.0
语文    300.0
dtype: float64

三、DataFrame

1. 什么是DateFrame

DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

  • 行索引:index
  • 列索引:columns
  • 值:values(numpy的二维数组)
DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
data:可以是ndarray、可迭代对象、字典等
index:生成索引(行),不指定默认为RangeIndex
columns:生成列标签,不指定默认为RangeIndex
dtype:要强制执行的数据类型。只允许一个dtype。如果没有,推断出
2. DataFrame的创建
2.1 给定参数来创建
# 推荐写法
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df = DataFrame(data=data, index=index, columns=columns)
df
>>
	语文	数学	英语	python
张三	102	149	127	148
李四	40	84	16	39
王五	82	124	28	17
赵六	46	137	148	96
2.2 字典创建
# 字典创建DataFrame, 字典的key是列索引
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)}, index = ['张三', '李四', '王五', '赵六'])
# df.index = ['张三', '李四', '王五', '赵六']
df
>>
	语文	数学	英语	python
张三	146	24	107	70
李四	135	26	54	38
王五	113	135	103	117
赵六	30	3	23	102
dict = {'张三':[150,150,150,300],'李四':[0,0,0,0]}
index = ['语文', '数学', '英语', '理综']
df = DataFrame(dict, index=index)
df
>>
	张三	李四
语文	150	0
数学	150	0
英语	150	0
理综	300	0
2.3 练习
============================================

练习4:

根据以下考试成绩表,创建一个DataFrame,命名为df:

    张三  李四
语文 150  0
数学 150  0
英语 150  0
理综 300  0
============================================
#方法1
dict = {'张三':[150,150,150,300],'李四':[0,0,0,0]}
index = ['语文', '数学', '英语', '理综']
df = DataFrame(dict, index=index)
df
>>
	张三	李四
语文	150	0
数学	150	0
英语	150	0
理综	300	0
#方法2
data = [[150, 0], [150, 0], [150, 0], [300, 0]]
index = ['语文', '数学', '英语', '理综']
columns = ['张三', '李四']
df = DataFrame(data=data, index=index, columns=columns)
df
3.DataFrame的属性
3.1 values、columns、index、shape

DataFrame属性:values、columns、index、shape

以2.2df为例:

df.values
>>array([[146,  24, 107,  70],
       [135,  26,  54,  38],
       [113, 135, 103, 117],
       [ 30,   3,  23, 102]])
       
df.shape
>>(4, 4)

# 行索引
df.index
>>Index(['张三', '李四', '王五', '赵六'], dtype='object')

# 列索引
df.columns
>>Index(['语文', '数学', '英语', 'python'], dtype='object')
4. DataFrame的索引和切片
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df = DataFrame(data=data, index=index, columns=columns)
df
>>
	语文	数学	英语	python
张三	121	143	60	33
李四	103	19	111	36
王五	117	33	109	38
赵六	1	106	40	122
4.1 对列进行操作
# 对列进行索引 ,推荐使用直接中括号.
- 通过类似字典的方式
df['语文']#推荐
- 通过属性的方式
df.语文
#结果一致
>>张三    121
李四    103
王五    117
赵六      1
Name: 语文, dtype: int32

可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

#返回DataFrame
df[['语文']]
>>
	语文
张三	121
李四	103
王五	117
赵六	1

#索引获取DataFrame多行方法
df[['语文','数学']]
>>
	语文	数学
张三	121	143
李四	103	19
王五	117	33
赵六	1	106
#新增一列
df['理综'] = np.random.randint(0,300, size=4)
df
>>
	语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86
赵六	1	106	40	122	265
#对列显式切片
df.loc[:, '数学': 'python']
>>
	数学	英语	python
张三	143	60	33
李四	19	111	36
王五	33	109	38
赵六	106	40	122

#对列隐式切片
df.iloc[:, 1:3]
	数学	英语
张三	143	60
李四	19	111
王五	33	109
赵六	106	40
4.2 对行进行操作
#索引
- 使用.loc[]加index来进行行索引
# 显式
df.loc[['张三', '李四']]#可以索引多个
>>
语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195

df.loc['张三']
语文        121
数学        143
英语         60
python     33
理综        160
Name: 张三, dtype: int32

- 使用.iloc[]加整数来进行行索引
df.iloc[[1]]
>>
	语文	数学	英语	python
李四	103	19	111	36

同样返回一个Series,index为原来的columns。
# 新增一行
df.loc['田七'] = np.random.randint(0,150, size=5)
df
>>
	语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86
赵六	1	106	40	122	265
田七	53	115	8	128	100
#行切片
# 操作行的时候,显式使用.loc
df.loc['张三': '王五']
>>
	语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86

# 使用隐式索引进行切片.
df.iloc[1:3]
>>
	语文	数学	英语	python	理综
李四	103	19	111	36	195
王五	117	33	109	38	86
4.3 对元素操作
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
# 先行后列,相当于一致对行进行操作
df.loc['王五'].loc['英语']
# 优化写法,也是推荐写法
df.loc['王五', '英语']
>>109
# 先列后行,相当于一致对列进行操作
df['英语']['王五']
>>109

#不可简化成df['英语', '王五']
#2, 找张三的语文成绩,要求返回的是一个DataFrame
df.loc[['张三'], ['语文']]
4.4 对比总结

【注意】 直接用中括号时:

  • 索引表示的是列索引
  • 切片表示的是行切片

总结:
1, 行索引永远用.loc[]
2, 列索引永远用[]
3, 索引元素的时候,先找行再找列,使用.loc[index, column]
4, 切片的时候,直接使用中括号是对行切片 , 对列进行切片也需要先从行开始 .loc[:, column: column]

​ 5,获得DataFrame格式添加[]

4.5 设置索引set_index
#设置索引set_index
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df = DataFrame(data=data, index=index, columns=columns)
df
>>
	语文	数学	英语	python
张三	57	118	95	78
李四	34	2	35	98
王五	18	73	24	137
赵六	84	80	128	74

df.set_index('语文')
>>
	数学	英语	python
语文			
57	118	95	78
34	2	35	98
18	73	24	137
84	80	128	74
4.6 练习
1, 找张三的语文成绩
2, 找张三的语文成绩,要求返回的是一个DataFrame
3, 切语文到英语
4, 切李四到赵六
df
>>
	语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86
赵六	1	106	40	122	265
田七	53	115	8	128	100
#1, 找张三的语文成绩
#先行后列(推荐简化版)
df.loc['张三'].loc['语文']
df.loc['张三','语文']

#先列后行
df['语文']['张三']

>>121
#2, 找张三的语文成绩,要求返回的是一个DataFrame
df.loc[['张三'], ['语文']]
#3, 切语文到英语
df.loc[:,'语文':'英语']
#4, 切李四到赵六
df.loc['李四':'赵六']
5. DataFrame的运算
5.1 DataFrame和单个数字的运算

各元素都进行运算

df + 1
>>
	语文	数学	英语	python	理综
张三	122	144	61	34	161
李四	104	20	112	37	196
王五	118	34	110	39	87
赵六	2	107	41	123	266
田七	54	116	9	129	101
5.2 DataFrame之间的运算

同Series一样:

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
#索引一致,对应位置元素进行运算
#DataFrame和DateFrame之间进行运算的时候,行列索引都一致的元素才能进行运算,否则补NaN
df2 = df.copy()
df2
>>
	语文	数学	英语	python	理综
张三	122	144	61	34	161
李四	104	20	112	37	196
王五	118	34	110	39	87
赵六	2	107	41	123	266
田七	54	116	9	129	101

df + df2
>>
	语文	数学	英语	python	理综
张三	242	286	120	66	320
李四	206	38	222	72	390
王五	234	66	218	76	172
赵六	2	212	80	244	530
田七	106	230	16	256	200
##DataFrame和DateFrame之间进行运算的时候,行列索引都一致的元素才能进行运算,否则补NaN
df2.columns = ['语文', '数学', '英语', 'python', '文综']
df2
>>
	语文	数学	英语	python	文综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86
赵六	1	106	40	122	265
田七	53	115	8	128	100

df + df2
>>
	python	数学	文综	理综	英语	语文
张三	66	286	NaN	NaN	120	242
李四	72	38	NaN	NaN	222	206
王五	76	66	NaN	NaN	218	234
赵六	244	212	NaN	NaN	80	2
田七	256	230	NaN	NaN	16	106

#增加填充,保留数据
df.add(df2, fill_value=0)
>>
	python	数学	文综	理综	英语	语文
张三	66	286	160.0	160.0	120	242
李四	72	38	195.0	195.0	222	206
王五	76	66	86.0	86.0	218	234
赵六	244	212	265.0	265.0	80	2
田七	256	230	100.0	100.0	16	106
5.3 Series与DataFrame之间的运算

【重要】

  • 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)

  • 使用pandas操作函数:

      axis=0:以列为单位操作(参数必须是列),对所有列都有效。
      axis=1:以行为单位操作(参数必须是行),对所有行都有效。
    
df#操作原型
>>
	语文	数学	英语	python	理综
张三	121	143	60	33	160
李四	103	19	111	36	195
王五	117	33	109	38	86
赵六	1	106	40	122	265
田七	53	115	8	128	100
s = Series(index=['语文', '数学', '英语', 'python', '理综'], data=np.random.randint(0,150, size=(5)))
s#创建一个series
>>语文        145
数学        117
英语          6
python    132
理综        113
dtype: int32

df + s#列索引一致时相加,相当于df中每一行都去与s进行对应相加
>>
	语文	数学	英语	python	理综
张三	266	260	66	165	273
李四	248	136	117	168	308
王五	262	150	115	170	199
赵六	146	223	46	254	378
田七	198	232	14	260	213
s = Series(index=['张三', '李四', '王五', '赵六', '田七'], data=np.random.randint(0,150, size=(5)))
s
>>张三      3
李四    123
王五    103
赵六     22
田七     28
dtype: int32

s + df # 列索引一致才进行运算,列索引不一致补NaN.
>>
	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	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
田七	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN

df.add(s, axis='index')
	语文	数学	英语	python	理综
张三	124	146	63	36	163
李四	226	142	234	159	318
王五	220	136	212	141	189
赵六	23	128	62	144	287
田七	81	143	36	156	128

总结:

  1. DataFrame和Series进行运算的时候,默认是按照DataFrame的列索引进行操作, 列索引一致才进行运算,列索引不一致补NaN.
    2)可以通过pandas封装的运算函数的axis来修改操作的方向.
5.4 练习
============================================

练习6:

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

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

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

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

后来老师发现数学有一道题答案直接打印了,给每位学生的数学都减10分,如何实现?

============================================
#操作原型,期中
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df1 = DataFrame(data=data, index=index, columns=columns)
df1
>>
	语文	数学	英语	python
张三	42	136	84	48
李四	129	80	124	40
王五	50	86	72	147
赵六	5	39	83	15
#假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df2 = DataFrame(data=data, index=index, columns=columns)
df2
>>
	语文	数学	英语	python
张三	67	83	104	104
李四	67	97	25	144
王五	144	24	47	28
赵六	95	28	48	42

(df1 + df2) / 2
>>
	语文	数学	英语	python
张三	71.0	78.0	130.5	42.0
李四	56.0	36.0	121.5	69.5
王五	102.0	23.0	88.5	82.5
赵六	89.0	54.5	82.0	97.5
#假设张三期中考试数学被发现作弊,要记为0分,如何实现?
df1.loc['张三','数学'] = 0
df1
>>
	语文	数学	英语	python
张三	42	0	84	48
李四	129	80	124	40
王五	50	86	72	147
赵六	5	39	83	15
#李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
df1.loc['李四'] + 100
df1
>>
	语文	数学	英语	python
张三	42	0	84	48
李四	229	180	224	140
王五	50	86	72	147
赵六	5	39	83	15
#后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
df1 + 10
>>
	语文	数学	英语	python
张三	52	10	94	58
李四	239	190	234	150
王五	60	96	82	157
赵六	15	49	93	25
#后来老师发现数学有一道题答案直接打印了,给每位学生的数学都减10分,如何实现?
df1['数学'] -= 10
df1

>>
	语文	数学	英语	python
张三	42	-10	84	48
李四	229	170	224	140
王五	50	76	72	147
赵六	5	29	83	15

6. Pandas自带的DataFrame算术运算方法

pandas中自带一些DataFrame的运算方法

DataFrame.add : Add DataFrames.#加
DataFrame.sub : Subtract DataFrames.#减
DataFrame.mul : Multiply DataFrames.#乘
DataFrame.div : Divide DataFrames (float division).#除
DataFrame.truediv : Divide DataFrames (float division).
DataFrame.floordiv : Divide DataFrames (integer division).
DataFrame.mod : Calculate modulo (remainder after division).#取模
DataFrame.pow : Calculate exponential power.#指数幂

详细:7、数据分析/day05/day14/Pandas自带算术运算方法.ipynb

四、处理Pandas丢失数据

有两种丢失数据:

  • None
  • np.nan(NaN)
1. None

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

type(None)
>>NoneType
1 + '1'
>>TypeError: unsupported operand type(s) for +: 'int' and 'str'
n = np.array([1,2,3,None])
n
>>array([1, 2, 3, None], dtype=object)

n.sum()
>>TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
'''object类型的运算要比int类型的运算慢得多
计算不同数据类型求和时间
%timeit np.arange(1e5,dtype=xxx).sum()'''
%timeit np.arange(1e5,dtype='int').sum()
>>238 µs ± 27.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.arange(1e5,dtype='float').sum()
>>303 µs ± 18 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.arange(1e5,dtype='object').sum()
12.5 ms ± 645 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2. np.nan(NaN)

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

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

type(np.nan)
>>floaat
n = np.array([1,2,3,np.nan])
n
>>array([ 1.,  2.,  3., nan])

n.sum()
>>nan

n.nansum(n)
>>6.0
3. pandas中的None与NaN
3.1 pandas中None与np.nan都视作np.nan
'''
创建DataFrame
使用DataFrame行索引与列索引修改DataFrame数据
'''
index = ['张三', '李四', '王五', '赵六']
columns = ['语文', '数学', '英语', 'python']
data = np.random.randint(0,150, size=(4,4,))
df1 = DataFrame(data=data, index=index, columns=columns)
df1
>>
	语文	数学	英语	python
张三	120	22	58	55
李四	133	47	82	2
王五	18	114	44	132
赵六	83	119	139	44

# 不推荐的写法.
df1['语文']['张三'] = np.nan
# 正确的写法
df1.loc['张三', '数学']  = None
df1
>>
	语文	数学	英语	python
张三	NaN	NaN	89	135
李四	115.0	0.0	93	27
王五	73.0	29.0	94	116
赵六	1.0	23.0	61	57
3.2 删除数据(拓展)
#drop 删除
df1.drop(
    labels=None,#指定要删除标签
    axis=0,#指定是行还是列操作,默认为0,操作行
    index=None,#指定删除的行
    columns=None,#指定删除的列
    level=None,
    inplace=False,#是否修改原操作模型
    errors='raise',
)
# 删除一行或者 一列数据
df1.drop(labels=['python'], axis=1, inplace=True)
>>
	 语文	    数学	  英语
张三	NaN	    NaN     58
李四	133.0	47.0	82
王五	18.0	114.0	44
赵六	83.0	119.0	139

df1.drop(index='赵六', columns='英语')
	语文	数学
张三	NaN	NaN
李四	133.0	47.0
王五	18.0	114.0
3.2 pandas中None与np.nan的操作

(1)判断函数

  • isnull()
  • notnull()
#整体判断
df1.isnull()/notnull()
pd.isnull/notnull(df1)
#isnull
	语文	数学	英语	python
张三	True	True	False	False
李四	False	False	False	False
王五	False	False	False	False
赵六	False	False	False	False
# 检测行或者列是否存在缺失数据
# 检测行
df1.isnull().any(axis=1)
>>张三     True
李四    False
王五    False
赵六    False
dtype: bool
    
# 检测列
df1.isnull().any(axis=0)
语文         True
数学         True
英语        False
python    False
dtype: bool  

(2) 过滤、删除函数

#drop 删除
df1.drop(
    labels=None,#指定要删除标签
    axis=0,#指定是行还是列操作,默认为0,操作行
    index=None,#指定删除的行
    columns=None,#指定删除的列
    level=None,
    inplace=False,#是否修改原操作模型
    errors='raise',
)
# 删除一行或者 一列数据
df1.drop(labels=['python'], axis=1, inplace=True)
>>
	 语文	    数学	  英语
张三	NaN	    NaN     58
李四	133.0	47.0	82
王五	18.0	114.0	44
赵六	83.0	119.0	139

df1.drop(index='赵六', columns='英语')
	语文	数学
张三	NaN	NaN
李四	133.0	47.0
王五	18.0	114.0

dd

# dropna删除缺失数据
df2.dropna(axis=0, #可以选择过滤的是行还是列(默认为行)
           how='any', #也可以选择过滤的方式,any:任一;all:全部
           thresh=None, 
           subset=None, #考虑的列标签,其他为NaN不考虑
           inplace=False)
# 删除缺失数据
df2 = df1.copy()
df2.dropna(axis=1)
>>
英语
张三	58
李四	82
王五	44
赵六	139
df2
>>
	语文	数学	英语
张三	NaN	NaN	NaN
李四	133.0	47.0	NaN
王五	18.0	114.0	44.0
赵六	83.0	119.0	NaN

df2.dropna(how='all')#全为NaN才删除
>>
语文	数学	英语
李四	133.0	47.0	NaN
王五	18.0	114.0	44.0
赵六	83.0	119.0	NaN

df2.dropna(subset=['语文', '数学'])#列标签为语文数学为NaN的才删除
>>
	语文	数学	英语
李四	133.0	47.0	NaN
王五	18.0	114.0	44.0
赵六	83.0	119.0	NaN

(3) 填充函数 Series/DataFrame

fillna主要有2种用法:

第一种使用指定的值去填充.

df2.fillna(value=100)

第二种, 使用已有的值去填充.又分为向前填充,和向后填充.

# method : {'backfill', 'bfill', 'pad', 'ffill', None}
# limit限制连续填充的次数
df2.fillna(method='bfill', axis=0, limit=3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值