处理丢失的数据
mysql中有没有丢失的数据?
- 在mysql中null就是列中的丢失数据
- 在pandas中丢失数据是NaN
# 导入需要用的模块
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
在python中有两种
- np.NaN
- None
df = DataFrame({'python':[100,101,np.nan,None], 'java':[110,120,119,None]})
df
# 结果如下:
# 聚合. sum()求和
# NaN在运算的时候并没有干扰正常的计算
df.sum(axis=1)
# NaN虽然没有干扰运算, 但是降低了我们计算的效率
# 结果如下:
0 210.0
1 221.0
2 119.0
3 0.0
dtype: float64
计算速度: int -> float -> object -> nan
%timeit np.arange(0,1e6,dtype=np.int).sum()
# 结果:1.95 ms ± 18.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit np.arange(0,1e6, dtype=np.float32).sum()
# 结果:.47 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.arange(0,1e6,dtype='object').sum()
# 结果:75.9 ms ± 6.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
python中None的类型本来就是object(NoneType)
numpy中的nan是浮点型
pandas 中对于空值的操作
- isnull() # 判断是否为空
- notnull() # 判断是否不为空
- dropna() # 过滤空值
- fillna() # 填充空值
isnull
cond = df.isnull()
# 返回bool值, nan为true
cond
# 结果如下:
notnull
cond = df.notnull()
cond
# 结果如下:
注意: 只有notnull得到的索引值可以通过df[cond]来获取相对应的值
any all
cond = df.isnull().any(axis=1)
cond
# axis = 0 表示对列进行操作, 有一个值为NaN那么返回true
# 结果如下:
0 False
1 False
2 True
3 True
dtype: bool
# ------------------------------------
cond = df.isnull().all(axis=1)
cond
# all条件全部为真,则返回true, 否则返回false
# 结果如下:
0 False
1 False
2 False
3 True
dtype: bool
# ------------------------------------
cond1 = df.notnull().all(axis=1)
cond1
# 结果如下:
0 True
1 True
2 False
3 False
dtype: bool
# ----------------------------------
cond1 = df.notnull().any(axis=1)
cond1
# 结果如下:
0 True
1 True
2 True
3 False
dtype: bool
dropna()
过滤NAN
df
# 结果如下:
# dropna() 将有空值的行直接删除
# 我们在丛数据分析的时候, 不会删除列(一般连数据都不会删除)
# 列不可以被删除? 身高一直会变化, 可能数据库这个值就是空值,
# 行相对于列来说不那么重要
df.dropna()
# how的作用是作为保留级别来使用的
df.dropna(how='all')
# 结果如下:
df1 = DataFrame({'python':[np.nan,None,100,101], 'java':[110,120,119,0]})
df1
fillna()
# 通过fillna将值为NAN的数全部填充为0
df4 = df.fillna(value=0)
df4
# 结果如下:
# method可选模式:{'backfill', 'bfill', 'pad', 'ffill', None}, default None
# Method to use for filling holes in reindexed Series
# pad / ffill: propagate last valid observation forward to next valid
# backfill / bfill: use NEXT valid observation to fill gap
# method='ffill' 找前面可用的数据, 向后填充, axis=0的时候拿前一行的值向后填充, axis=1的时候是找前一列的值进行填充
df4= df.fillna(method='ffill',axis=1)
df4
# 结果如下:
df5 = DataFrame({'python':[100,200,1,201,],'java':[300,100,400,500,],'php':[3,2,None,0]})
df5
# 结果如下:
# bfill 从后面找第一个值进行填充
df5.fillna(method='bfill', axis=1)
# 缺点, 如果前后左右任意一方出现无值的情况, 可能会报错
傅里叶公式运用
# 上帝看 : 内在 频率
# 人看世界: 表象, 时域, 肉眼能识别的
# 平原, 山丘 联想到平原和山丘的关系就是一种波动
# 波 原子->波 都是基础的物质
import numpy as np
# fft是傅里叶变换, ifft是反傅里叶变换
from numpy.fft import fft,ifft
from PIL import Image
import matplotlib.pyplot as plt
# 引入图片
cat = Image.open('./cat.jpg')
cat
# 图片如下:
# cat.tobytes()将猫图片对象转化为二进制的文本字符串
# np.fromstring(cat.tobytes(), np.int8) 从一个二进制文本字符串中初始化成一个int8的数组
# 注意:数组的数据类型;默认值:浮动。数据必须以二进制输入数据.
cat_data = np.fromstring(cat.tobytes(), np.int8)
cat_data
# 结果如: array([ -25, -70, -125, ..., -68, 95, 62], dtype=int8)
cat_fft = fft(cat_data)
# 将时域转换成频域 傅里叶的变换
cat_fft
# 结果如下:
array([-1569123. +0. j,
-7005918.98362136+12604783.28030717j,
-2819481.22749804 +8877463.78907501j, ...,
622731.5619853 -2775345.73593521j,
-2819481.22749811 -8877463.78907499j,
-7005918.98362145-12604783.28030712j])
# 求绝对值进行找出柔和的频率
cond = np.abs(cat_fft) < 1e4 *20
# 将这些柔和的频率去除
cat_fft[cond] = 0
# 将频域转换成时域
cat_ifft = ifft(cat_fft)
cat_ifft
# 结果如下:
array([-11.32971006+3.75426123e-13j, 39.6547189 -2.63766541e-13j,
-26.15791263-2.59052660e-13j, ..., -2.7618658 +5.85713493e-13j,
49.60338509-7.36865241e-14j, -11.30093432-7.42168361e-13j])
# 将虚数去除
cat_real = np.real(cat_ifft)
# 因为是jpg, 不需要浮点数
cat_result = np.int8(cat_real)
cat_result
# 结果:array([-11, 39, -26, ..., -2, 49, -11], dtype=int8)
--------------------------------------
cat_lunkuo = Image.frombytes(mode='RGB', size=(730, 456), data=cat_result)
cat_lunkuo
# 经过傅里叶运算后的图片如下:
pandas层次化索引
# 导入所需要的包
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
1. 创建多层行索引
1) 隐式构造
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组
- Series也可以创建多层索引
s = Series(np.random.randint(0,150,size=6),
index=[['a','a','b','b','c','c'],
['期中','期末','期中','期末','期中','期末']])
s
# 结果如下:
# 将Series对象s传入DataFrame中, 并命名列名为python
df = DataFrame(s, columns=['python'])
df
# 结果如下:
DataFrame建立2级列索引
df1 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=[['python','python','math','math','En','En'], ['期中','期末','期中','期末','期中','期末']])
df1
2) 显示构造pd.MultiIndex
- 使用 MultiIndex.from_tuples()
df3 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=pd.MultiIndex.from_tuples([('python','期中'),('python','期末'),
('math','期中'),('math','期末'),
('En','期中'),('En','期末')]))
df3
# 结果如下:
- 使用product
最简单,推荐使用
df4 = DataFrame(np.random.randint(0,150,size=(4,6)),
index=list('东南西北'),
columns=pd.MultiIndex.from_product([['python','math','En'],
['期中','期末']]))
df4
# 结果如下:
============================================
练习8:
- 创建一个DataFrame,表示出张三李四期中期末各科成绩
============================================
DataFrame(np.random.randint(0,150,size=(4,4)),
index=pd.MultiIndex.from_product([['张三','李四'],['期中','期末']]),
columns=pd.MultiIndex.from_product([['语文','数学','英语','python']]))
# 结果如下:
2. 多层列索引
除了行索引index,列索引columns也能用同样的方法创建多层索引
df4 = DataFrame(np.random.randint(0,150,size=(8,12)),
columns=pd.MultiIndex.from_product([['模拟考','正式考'],
['数学','语文','英语','物理','化学','生物']]),
index=pd.MultiIndex.from_product([['期中','期末'],
['雷军','李斌'],
['测试一','测试二']]))
df4
3. 多层索引对象的索引与切片操作
1)Series的操作
【重要】对于Series来说,直接中括号[]与使用.loc()完全一样,因此,推荐使用中括号索引和切片。
s
# 结果如下:
切片与索引
# 取多层的外层索引时, 内层索引不可用
s[['a','b']]
# 除此之外还有以下的索引获取值的方式
s.a.期中
s['a'][['期中','期末']]['期末']
s.loc['a'] #注意.loc可以是第一个列表用于取行
s.iloc[:5] #注意: 通过隐式索引取值都是取到最内层索引的值
2)DataFrame的操作
(1) 可以直接使用列名称来进行列索引
(2) 使用行索引需要用ix(),loc()等函数
【极其重要】推荐使用loc()函数
注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!
df4
# 结果如下:
# 索引查询
df4['模拟考'][['语文','数学']]
# 结果如下:
# 还可以通过以下方式进去获取:
# loc 和 iloc都是从行还是取 的, 没有loc和iloc是从列开始取的 第二个列表才是行
df4.loc['期中','雷军','测试一']['模拟考','数学']
df4.iloc[0]
# 用.来取索引值只能先将列取完才能取行, 同理 先取行必须取完才能取列索引
df4.模拟考.数学.期中.雷军.测试二
df4['模拟考']
============================================
练习9:
分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法
假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?
============================================
4. 索引的堆(stack)
stack()
unstack()
【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。
df2
# 查询结果:
# stack的作用是将<列>索引变成了<行>最内层的索引
# level 代表的是层级, 默认为-1 代表为最内层
df2.stack(level=1)
【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
# unstack 是将<行>索引编程列的最<内>层索引 level默认-1, 也就是最内层的行索引
df4.unstack()
# 如果想把所有的<行>索引都转成<列>索引, 怎么办?
# 给level一个list , 可以解决
df4.unstack(level=[0,1,2])
模拟考 数学 期中 李斌 测试一 130
测试二 119
雷军 测试一 51
测试二 108
期末 李斌 测试一 88
测试二 127
雷军 测试一 74
测试二 141
语文 期中 李斌 测试一 95
测试二 119
雷军 测试一 5
测试二 129
期末 李斌 测试一 71
测试二 63
雷军 测试一 36
测试二 66
英语 期中 李斌 测试一 108
测试二 27
雷军 测试一 53
测试二 67
期末 李斌 测试一 75
测试二 37
雷军 测试一 19
测试二 30
物理 期中 李斌 测试一 29
测试二 16
雷军 测试一 126
测试二 94
期末 李斌 测试一 119
测试二 24
...
正式考 英语 期中 雷军 测试一 64
测试二 92
期末 李斌 测试一 87
测试二 47
雷军 测试一 118
测试二 47
物理 期中 李斌 测试一 138
测试二 67
雷军 测试一 124
测试二 86
期末 李斌 测试一 37
测试二 98
雷军 测试一 27
测试二 104
化学 期中 李斌 测试一 11
测试二 112
雷军 测试一 14
测试二 38
期末 李斌 测试一 114
测试二 61
雷军 测试一 106
测试二 4
生物 期中 李斌 测试一 108
测试二 97
雷军 测试一 101
测试二 146
期末 李斌 测试一 49
测试二 149
雷军 测试一 18
测试二 109
Length: 96, dtype: int32
练习10:
使用unstack()将sf4变为两行,分别为期中期末
使用unstack()将ddd变为四行,分别为四个科目
============================================
# 1.
df4.unstack(level=[1,2])
# 2.
df4.unstack() #结果没有展示
# 结果:
5. 聚合操作
【注意】
需要指定axis
【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就保留。
所谓的聚合操作:平均数,方差,最大值,最小值……
df2
# 结果如下:
df2.sum(axis=0)
# 结果如下:
df2.std(axis=1) # 求列方向的方差
df2.max(axis=1) # 求列方向的最大值
df2.max(axis=0) # 求行方向的最大值
df2.sum(axis=1)
# 结果如下:
============================================
练习11:
计算各个科目期中期末平均成绩
计算各科目张三李四的最高分
============================================
# 1.计算各个科目期中期末平均成绩
df4.mean(axis=0, level=(0))
# 结果:
# 2.计算各科目张三李四的最高分
df4.max(level=(1))
# 结果