数据分析与AI(四)pandas处理丢失的数据/傅里叶公式实验/pandas层次化索引检索

处理丢失的数据

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:

  1. 创建一个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:

  1. 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法

  2. 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?

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

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:

  1. 使用unstack()将sf4变为两行,分别为期中期末

  2. 使用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. 计算各个科目期中期末平均成绩

  2. 计算各科目张三李四的最高分

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

# 1.计算各个科目期中期末平均成绩
df4.mean(axis=0, level=(0))
# 结果:

这里写图片描述

# 2.计算各科目张三李四的最高分
df4.max(level=(1))
# 结果

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_41637554/article/details/80699019
今日推荐