第3章 Pandas数据处理(3.4-3.5)_Python数据科学手册学习笔记
3.4 Pandas 数值运算方法
对于一元运算(像函数与三角函数),这些通用函数将在输出结果中保留索引和列标签; 而对于二元运算(如加法和乘法), Pandas在传递通用函数时会自动对齐索引进行计算. 这就意味着,保存数据内容和组合不同来源的数据—两处在NumPy数组中容易出错的地方,变成了Pandas的杀手锏.
3.4.1 通用函数: 保留索引
因为Pandas是建立在NumPy基础之上的, 所以NumPy的通用函数也同样适用于Pandas的Series和DataFrame.
import pandas as pd import numpy as np[/code]
rng = np.random.RandomState(42) ser = pd.Series(rng.randint(0,10,4)) ser[/code]
0 6 1 3 2 7 3 4 dtype: int32
df = pd.DataFrame(rng.randint(0,10,(3,4)),columns=['a','b','c','d']) # 列标签只有4个,必须和数组列数量一致 df[/code]
a | b | c | d | |
---|---|---|---|---|
0 | 6 | 9 | 2 | 6 |
1 | 7 | 4 | 3 | 7 |
2 | 7 | 2 | 5 | 4 |
3.4.2 通用函数: 索引对齐
当在两个Series或DataFrame对象进行二元计算时, Pandas会在计算过程中对齐两个对象的索引.
Series索引对齐
rk = pd.Series({'湖北':1234,'湖南':3242,'广东':3233},name='人口') # Series有个name属性, 可以作为DataFrame列名称吗 mj = pd.Series({'湖北':123,'湖南':321,'山东':21},name='面积') rk /mj[/code]
山东 NaN 广东 NaN 湖北 10.032520 湖南 10.099688 dtype: float64
结果数组的索引是两个数组的并集. 也可以用另一种运算法则
rk.index | mj.index[/code]
Index(['山东', '广东', '湖北', '湖南'], dtype='object')
a = pd.Series([2,4,6],index=[0,1,2]) b = pd.Series([1,3,5],index=[1,2,3]) a + b # 为什么不把缺失的当0处理呢?[/code]
0 NaN 1 5.0 2 9.0 3 NaN dtype: float64
a | b # a 并 b 表示什么意思[/code]
0 True 1 True 2 True 3 False dtype: bool
a & b # a 交 b 表示什么意思[/code]
0 False 1 False 2 False 3 False dtype: bool
a ^ b[/code]
0 True 1 True 2 True 3 False dtype: bool
a * b[/code]
0 NaN 1 4.0 2 18.0 3 NaN dtype: float64
a.add(b,fill_value=0) # 缺失值当0处理[/code]
0 2.0 1 5.0 2 9.0 3 5.0 dtype: float64
DataFrame索引对齐
在计算两个DataFrame时, 类似的索引对齐规则同样会出现在共同列中
A = pd.DataFrame(rng.randint(0,20,(2,2)),columns=list("AB")) # 生成一个2*2的数组,数值都小于20. DataFrame列用list('AB')生成 B = pd.DataFrame(rng.randint(0,20,(3,3)),columns=list('ABC')) print(A) print('*'*20) print(B) print('*'*20) print(A+B)[/code]
A B 0 1 11 1 5 1 ******************** A B C 0 0 11 11 1 16 9 15 2 14 14 18 ******************** A B C 0 1.0 22.0 NaN 1 21.0 10.0 NaN 2 NaN NaN NaN
处理方法一: 用A中所有值得均值来填充缺失值. 计算A的均值需要用stack将二维数组压缩成一维数组
fill = A.stack().mean() print(fill) A.add(B,fill_value=fill) # 比较下维度差,A数组缺的位置,都用均值填充[/code]
4.5
A | B | C | |
---|---|---|---|
0 | 1.0 | 22.0 | 15.5 |
1 | 21.0 | 10.0 | 19.5 |
2 | 18.5 | 18.5 | 22.5 |
Python运算符和Pandas方法的映射关系(下面必须空一行)
Python运算符 | Pandas方法 |
---|---|
+ | add() |
- | sub(),subtract() |
* | mul(),multiply() |
/ | truediv(),div(),divide() |
// | floordiv() |
% | mod() |
** | pow() |
3.4.3 通用函数: DataFrame与Series的运算
一个二维数组减去自身的一行数据
rng = np.random.RandomState(42) a = rng.randint(10,size=(3,4)) print(type(a)) a[/code]
<class 'numpy.ndarray'> array([[6, 3, 7, 4], [6, 9, 2, 6], [7, 4, 3, 7]])
a - a[0] # 0 表示第1行[/code]
array([[ 0, 0, 0, 0], [ 0, 6, -5, 2], [ 1, 1, -4, 3]])
df = pd.DataFrame(a,columns=list('QRST')) pd.DataFrame(a,columns=['q','r','s','t']) pd.DataFrame(a,columns=('a','b','c','d')) print(df)[/code]
Q R S T 0 6 3 7 4 1 6 9 2 6 2 7 4 3 7
一个DataFrame减去自身第1行
print(df-df.iloc[0]) print(df.subtract(df['R'],axis=0) #此句报错, 可能是2.7 和3.+版本不兼容问题[/code]
File "<ipython-input-49-0b4659832f8f>", line 2 print(df.subtract(df['R'],axis=0) ^ SyntaxError: unexpected EOF while parsing
3.5 处理缺失值
三种方法: null, NaN 和NA.
识别缺失值的方法: 通过一个覆盖全局的掩码表示缺失值, 另一种方法用一个标签纸表示.
3.5.2 Pandas的缺失值
Pandas最终选择用标签方法表示缺失值, 包括两种Python原有的缺失值: 浮点数据类型的NaN值, 以及Python的None对象. 后面我们将会发现,虽然这么做也有一些副作用, 但是在实际运用中够用.
None: Python对象类型的缺失值
- None是一个Python单体对象, 经常在代码中表示缺失值. 由于None是一个Python对象, 所以不能作为任何NumPy/Pandas数组类型的缺失值, 只能用于’object’数据类型(即由Python对象构成的数组). 什么意思?
x1 = np.array([1,None,3,4]) x1[/code]
array([1, None, 3, 4], dtype=object)
使用Python对象构成的数组就意味着你对一个包含None的数组进行累计操作,如sum()和min(),通常会报错: 为什么?
x1.sum()[/code]
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-52-0c8c176901d3> in <module>() ----> 1 x1.sum() D:\Anaconda3\lib\site-packages\numpy\core\_methods.py in _sum(a, axis, dtype, out, keepdims) 30 31 def _sum(a, axis=None, dtype=None, out=None, keepdims=False): ---> 32 return umr_sum(a, axis, dtype, out, keepdims) 33 34 def _prod(a, axis=None, dtype=None, out=None, keepdims=False): TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
NaN: 数值类型的缺失值
- NaN(全程 Not a Number), 在任何系统中都兼容的特殊浮点数
x2 = np.array([1,np.nan,3,4]) # 要写成 np.nanx2.dtype[/code]
dtype('float64')
NaN就像病毒一样会将它接触过的数据同化
1 + np.nan[/code]
nan
0 + np.nan[/code]
nan
x2.sum(),x2.max(),x2.min()[/code]
(nan, nan, nan)
NumPy也提供了一些特殊的累计函数, 可以忽略缺失值的影响
np.nansum(x2), np.nanmin(x2), np.nanmax(x2) # x2.nansum() 报错[/code]
(8.0, 1.0, 4.0)
Pandas中NaN与None的差异
- Pandas把它们看成是可以等价交换的, 在适当的时候会将两者进行替换.
- Pandas会将没有标签值得数据类型自动转换成NA
3.5.3 处理缺失值
发现,剔除,替换数据中的缺失值的方法:
- isnull(), 创建一个布尔类型的掩码标签缺失值
- notnull(), 与isnull()相反的操作
- dropna(), 返回一个剔除缺失值的数据
- fillna(), 返回一个填充了缺失值的数据副本
发现缺失值
- Pandas中有两种有效的方法可以发现缺失值: isnull()和notnull(),都返回布尔类型的掩码数据.
data = pd.Series([1,np.nan,'Hello',None]) data.isnull()[/code]
0 False 1 True 2 False 3 True dtype: bool
data[data.notnull()][/code]
0 1 2 Hello dtype: object
剔除缺失值
- dropna(),剔除缺失值
- fillna(),填充缺失值
data.dropna()[/code]
0 1 2 Hello dtype: object
而在DataFrame上使用时需要设置一些参数
df = pd.DataFrame([[1,np.nan,2], [2,3,5], [np.nan,4,6]]) df[/code]
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
没法从DataFrame中单独剔除一个值, 要么是剔除缺失值所在的整行,要么是整列. 根据实际需求.
- 默认情况下,dropna(),会剔除任何包含缺失值的整行数据
df.dropna()[/code]
0 | 1 | 2 | |
---|---|---|---|
1 | 2.0 | 3.0 | 5 |
可以设置参数 axis=1 剔除任何包含缺失值的整列数据
df.dropna(axis=1)[/code]
2 | |
---|---|
0 | 2 |
1 | 5 |
2 | 6 |
df[3] = np.nan # 增加第4列,都为缺失值 df[/code]
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 1.0 | NaN | 2 | NaN |
1 | 2.0 | 3.0 | 5 | NaN |
2 | NaN | 4.0 | 6 | NaN |
df.dropna(axis='columns',how='all') # 如果某一个列全为缺失值,则删除 ,how的参数还可以等于any, 默认是any[/code]
0 | 1 | 2 | |
---|---|---|---|
0 | 1.0 | NaN | 2 |
1 | 2.0 | 3.0 | 5 |
2 | NaN | 4.0 | 6 |
还可以通过参数thresh设置非缺失值的最小数量
填充缺失值
data = pd.Series([1,np.nan,2,None,3],index=list("abcde")) data[/code]
a 1.0 b NaN c 2.0 d NaN e 3.0 dtype: float64
用一个单独的值来填充缺失值,比如0或者100
data.fillna(0) data.fillna(100)[/code]
a 1.0 b 100.0 c 2.0 d 100.0 e 3.0 dtype: float64
可以用缺失值前面的有效值来从前往后填充
# 从前往后填充 data.fillna(method='ffill')[/code]
a 1.0 b 1.0 c 2.0 d 2.0 e 3.0 dtype: float64
# 从后往前填充 data.fillna(method='bfill')[/code]
a 1.0 b 2.0 c 2.0 d 3.0 e 3.0 dtype: float64
注意: 如果从前往后填充时, 需要填充的缺失值前面没有值, 那么它就仍然是缺失值.
阅读更多- 第3章 Pandas数据处理(3.11-3.13)_Python数据科学手册学习笔记
- 第3章 Pandas数据处理(3.7-3.8)_Python数据科学手册学习笔记
- 第3章 Pandas数据处理(3.6)_Python数据科学手册学习笔记
- 第3章 Pandas数据处理(3.9-3.10)_Python数据科学手册学习笔记
- 第2章 NumPy入门(2.1-2.2)_Python数据科学手册学习笔记
- 利用Pythonj进行数据分析学习笔记——第五章 pandas入门
- python数据挖掘学习笔记】十.Pandas、Matplotlib、PCA绘图实用代码补充
- 从零开始学Python学习笔记---之--pandas数据框(1)
- python数据分析学习笔记-Numpy-Matplotlib-Pandas
- python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例
- 从零开始学Python学习笔记---之--pandas数据框(2)
- 从零开始学Python学习笔记---之--pandas数据框(3)
- Python爬虫(入门+进阶)学习笔记 1-5 使用pandas保存豆瓣短评数据
- python学习笔记(二)——数据类型
- python学习手册笔记--第10章--语句简介--第11章--复制_表达式_打印
- Python学习笔记一:数据类型转换
- Python源码学习笔记(1 基本数据类型)
- JQuery 参考手册 学习笔记(3)-jquery 数据缓存、队列控制
- python学习手册笔记--第16~19章--function_base
- python学习手册笔记--第25,28,30,32章