ndarray中nan的替换(均值)
ndarray中存在nan,如何操作才能够将nan替换为每一列的均值?
# 判断这一列中是否有nan数据
for i in range(arr.shape[1]): # 对列进行遍历
current_col=arr[:,i] # 当前的这一列
# 判断当前的这一列中是否有nan数据 如果有 有几个
nan_num=np.count_nonzero(current_col!=current_col) # 这一列中nan数据的个数
if nan_num!=0: # 说明这一列数据中有nan数据
not_nan_array=current_col[current_col==current_col] # 取出这一列中不为nan的数据 返回的是一个数组
# 求出这一列中不为nan的数据构成的数组的均值 arr.mean()
# 用这一列的均值来替换这一列的nan数据
# 取出这一列的nan数据
# current_col[current_col!=current_col]
# current_col[np.isnan(current_col)]
# np.isnan(arr) 将数组中的nan数据标记为True 否则标记为False
current_col[np.isnan(current_col)]=not_nan_array.mean() # 赋值
由于 使用这一列的均值来填充这一列的缺失值数据
是一种很常用的方法,所以我们可以将这个方法定义为一个函数,以后需要使用的时候直接调用这个函数就可以了
简单看一下效果怎么样
先创造一个含有缺失值的数组对象
然后再调用这个函数
结果是正确的,我们可以看见,最后返回的数组对象中,它的缺失值部分的确是用这一列的均值来代替了。
这是完整的代码
# -*- coding: utf-8 -*-
'''
@Time : 2020/12/05 19:49
@Author : yuhui
@Email : 3476237164@qq.com
@FileName: numpy_2.py
@Software: PyCharm
'''
"""19【numpy中的nan和常用方法】01numpy中的nan和常用统计方法"""
import numpy as np
def fill_array_nan(arr):
"""
:param arr: 含有nan缺失值的数组对象
:return: 用这一列的平均值来替换这一列的缺失值
"""
# 对这个数组进行列遍历
for i in range(arr.shape[1]):
current_col=arr[:,i] # 取出当前正在被遍历的一列
# 检查当前的这一列中是否存在nan缺失值 如果有 有几个
nan_array = current_col[current_col != current_col] # 这一列中缺失值的数组
if nan_array is not None: # 数组不为空 说明存在缺失值
not_nan_array = current_col[current_col == current_col] # 这一列中不为nan的数据
# 用正常值的均值来替换这一列的缺失值数据
# current_col[current_col!=current_col]=not_nan_array.mean()
# 下面这种也可以 相当于是current_col[current_col!=current_col]
current_col[np.isnan(current_col)] = not_nan_array.mean()
return arr # 返回替换之后的数组对象
if __name__ == '__main__':
arr = np.arange(20).reshape(4, 5).astype("float32")
arr[2:,:] = np.nan
print(arr)
print("*"*50)
print(fill_array_nan(arr))
小的知识点
1.如何对数组进行行遍历
2.如何对数组进行列遍历
3.检查数组中是否存在缺失值数据 如果有 有几个
1.判断缺失值的数量是否为0
缺失值的数量:
np.count_nonzero(np.isnan(arr))
np.count_nonzero(arr!=arr)
2.判断缺失值的数组对象是否为空
缺失值的数组对象
arr[np.isnan(arr)]
arr[arr!=arr]
这个时候,我们又得到了两种取数组中缺失值数量的方法:
len(arr[np.isnan(arr)])
len(arr[arr!=arr])
小结
- 如何选择一行或者多行的数据(列)?
- 如何给选取的行或者列赋值?
- 如何大于把大于10的值替换为10?
- np.where如何使用?
- np.clip如何使用?
- 如何转置(交换轴)?
- 读取和保存数据为csv?
- np.nan和np.inf是什么?
- 常用的统计函数你记得几个?
- 标准差反映出数据的什么信息?
动手
现在这里有一个英国和美国各自youtube1000多个视频的【点击】【喜欢】【不喜欢】【评论数量】([“views”,“likes”,“dislikes”,“comment_total”])的Excel文件,运用所学习的知识,完成下面的两个练习。
数据来源:https://www.kaggle.com/datasnaek/youtube/data
例题1
利用已经学习过的知识和英国、美国各自youtube1000的数据绘制出各自的评论数量的直方图。
原始数据
美国youtube1000的数据
代码+分析+结果
# -*- coding: utf-8 -*-
'''
@Time : 2020/12/08 16:24
@Author : yuhui
@Email : 3476237164@qq.com
@FileName: numpy_3.py
@Software: PyCharm
'''
"""20【numpy中的nan和常用方法】numpy中填充nan"""
import numpy as np
import matplotlib.pyplot as plt
# 解决中文乱码
plt.rcParams["font.sans-serif"]=["KaiTi"]
plt.rcParams["font.family"]="sans-serif"
# 解决符号无法显示的问题
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时负号'-'显示为方块的问题
"""设置图形大小和图片品质"""
fig=plt.figure(
figsize=(16,9),
dpi=100,
)
us_file_path=r"D:\Python\数据分析\数据分析2\data\us.csv"
us=np.loadtxt(us_file_path, # 文件路径
dtype="int32", # 数据类型
delimiter=",", # 分隔符
skiprows=1 # 跳过开头的几行
)
us_comments=us # us的评论数量 所有的行 第0列
"""绘制直方图"""
# 打印出最大值和最小值 根据最大值和最小值确定出组距,进而确定组数
# print(us_comments.max(),us_comments.min()) # 4996 117
# 组距
group_spacing=250
# 组数
num_bins=(us_comments.max()-us_comments.min())//group_spacing
# 绘制直方图
plt.hist(us_comments,num_bins,
color="#6495ED", # 颜色
)
"""设置x轴刻度"""
plt.xticks(range(min(us_comments),max(us_comments)+group_spacing,group_spacing))
"""绘制网格线"""
plt.grid(
linestyle=":", # 线型
color="#6495ED", # 颜色 CornflowerBlue 矢车菊的蓝色 #6495ED 100,149,237
alpha=0.4, # 透明度
)
plt.show()
显然,这次的结果是不够好的,有许多地方都需要改进一下。
那么,我们应该如何处理我们的组距和组数呢?
要想直方图的外部轮廓线和背景网格线对齐,最好是
修改一下组距
# 打印出最大值和最小值 根据最大值和最小值确定出组距,进而确定组数
# print(us_comments.max(),us_comments.min()) # 4996 117
# 组距
group_spacing=17*41
# 4996-117=4879=7*17*41
# 组数
num_bins=(us_comments.max()-us_comments.min())//group_spacing # =7*17*41/(17*41)=7 # 整数
结果如下
在以后我们使用Python进行绘图时,图形的美观只是一方面,我们最根本的目的其实还是希望能够从图形中获得数据的规律,总结这些规律并且能够让我们使用。所以判断一个图形的优劣的第一标准应该是这个图形是否能够展现数据的规律,这才是最重要的,其余的都是其次重要的。不过如果说你能够在满足第一要求的情况下,还能够将这个图形做得尽可能的美观,那你的这次绘图工作可以说就是相当的成功了。
这是全部的代码
# -*- coding: utf-8 -*-
'''
@Time : 2020/12/08 16:24
@Author : yuhui
@Email : 3476237164@qq.com
@FileName: numpy_3.py
@Software: PyCharm
'''
"""20【numpy中的nan和常用方法】numpy中填充nan"""
import numpy as np
import matplotlib.pyplot as plt
# 解决中文乱码
plt.rcParams["font.sans-serif"]=["KaiTi"]
plt.rcParams["font.family"]="sans-serif"
# 解决符号无法显示的问题
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时负号'-'显示为方块的问题
"""设置图形大小和图片品质"""
fig=plt.figure(
figsize=(16,9),
dpi=100,
)
us_file_path=r"D:\Python\数据分析\数据分析2\data\us.csv"
us=np.loadtxt(us_file_path, # 文件路径
dtype="int32", # 数据类型
delimiter=",", # 分隔符
skiprows=1 # 跳过开头的几行
)
us_comments=us # us的评论数量 所有的行 第0列
"""绘制直方图"""
# 打印出最大值和最小值 根据最大值和最小值确定出组距,进而确定组数
# print(us_comments.max(),us_comments.min()) # 4996 117
# 组距
group_spacing=17*41
# 4996-117=4879=7*17*41
# 组数
num_bins=(us_comments.max()-us_comments.min())//group_spacing # =7*17*41/(17*41)=7 # 整数
# 绘制直方图
plt.hist(us_comments,num_bins,
color="#6495ED", # 颜色
)
"""设置x轴刻度"""
plt.xticks(range(min(us_comments),max(us_comments)+group_spacing,group_spacing))
"""绘制网格线"""
plt.grid(
linestyle=":", # 线型
color="#6495ED", # 颜色 CornflowerBlue 矢车菊的蓝色 #6495ED 100,149,237
alpha=0.4, # 透明度
)
plt.show()
例题2
希望了解英国的youtube1000的数据中视频的评论数和喜欢数的关系,应该如何绘制图形?
原始数据
英国youtube1000的数据
代码+分析+结果
根据题目要求,为了表现出两者(comment_total
和likes
)之间的关系,我们应该绘制散点图,其中横轴数据为comment_total
,纵轴数据为likes
。
# -*- coding: utf-8 -*-
'''
@Time : 2020/12/08 16:36
@Author : yuhui
@Email : 3476237164@qq.com
@FileName: numpy_4.py
@Software: PyCharm
'''
"""20【numpy中的nan和常用方法】numpy中填充nan"""
import numpy as np
import matplotlib.pyplot as plt
# 解决中文乱码
plt.rcParams["font.sans-serif"]=["KaiTi"]
plt.rcParams["font.family"]="sans-serif"
# 解决符号无法显示的问题
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时负号'-'显示为方块的问题
"""设置图形大小和图片品质"""
fig=plt.figure(
figsize=(16,9),
dpi=100,
)
uk_file_path=r"D:\Python\数据分析\数据分析2\data\uk.csv"
uk=np.loadtxt(uk_file_path,
dtype="int32",
delimiter=",",
skiprows=1, # 跳过第一行
)
comments=uk[:,1] # 横轴数据 第二列
likes=uk[:,0] # 纵轴数据 第一列
"""绘制散点图"""
plt.scatter(comments,likes)
plt.show()
结果如下
为什么这个散点图的规律会这么明显呢?
因为这数据是我自己做的:先通过随机数生成数据,然后对和数据进行升序排列,最后在写代码运行的时候就出现了这样的效果。
其实数据并不重要,重要的是我们处理数据的方法,掌握了方法之后,以后在面对这样的例题时我们就知道应该如何处理对应的数据了。