数据科学库(HM)DAY 3

这篇博客详细介绍了Python的科学计算库numpy,包括如何创建和操作数组、理解广播原则、掌握轴(axis)概念、读取本地数据、数组转置、数值修改,以及numpy中的nan和inf处理。此外,还探讨了numpy的常用统计函数,并结合matplotlib展示了数据可视化的方法。
摘要由CSDN通过智能技术生成

numpy学习

什么是numpy

一个在Python中做科学计算的基础库,重在数值计算,也是大部分PYTHON科学计算库的基础库,多用于在大型、多维数组上执行数值运算。

numpy创建数组(矩阵)

import numpy as np

#使用numpy生成数组,得到ndarray的类型
t1 = np.array([1,2,3])
print(t1)
print(type(t1))

t2 = np.array(range(10))
print(t2)
print(type(t2))

t3 = np.arange(4,10,2) # arange()等价于array(range())
print(t3)
print(type(t3))
print(t3.dtype)

运行结果:

[1 2 3]
<class 'numpy.ndarray'>
[0 1 2 3 4 5 6 7 8 9]
<class 'numpy.ndarray'>
[4 6 8]
<class 'numpy.ndarray'>
int32

默认整数类型np.int_是C long,但是C long在win64中是int32.

numpy中常见的更多数据类型

在这里插入图片描述

数据类型的操作

import numpy as np
import random

#指定创建数组的数据类型
t4 = np.array(range(1,4),dtype=float)
print(t4)
print(t4.dtype)

#numpy中的bool类型
t5 = np.array([1,0,1,1,0],dtype=bool)
print(t5)
print(t5.dtype)

#调整数据类型
t6 = t5.astype("int8")
print(t6)
print(t6.dtype)

#numpy中的小数
t7 = np.array([random.random() for i in range(10)])
print(t7)
print(t7.dtype)
print(np.round(t7,3)) #保留3位小数

运行结果:

[1. 2. 3.]
float64
[ True False  True  True False]
bool
[1 0 1 1 0]
int8
[0.40965587 0.65607682 0.55963194 0.17005824 0.97233548 0.20681428
 0.37630063 0.45185797 0.40072167 0.32030872]
float64
[0.41  0.656 0.56  0.17  0.972 0.207 0.376 0.452 0.401 0.32 ]

数组的形状

查看数组的形状:

import numpy as np

t1 = np.array(range(10))
print(t1)
print(t1.shape) #一维数组
print("#######################################")
t2 = np.array([[0,1,2,3,4],[5,6,7,8,9]])
print(t2)
print(t2.shape) #二维数组
print("#######################################")
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape) #三维数组
print("#######################################")

运行结果:

[0 1 2 3 4 5 6 7 8 9]
(10,)
#######################################
[[0 1 2 3 4]
 [5 6 7 8 9]]
(2, 5)
#######################################
[[[ 1  2  3]
  [ 4  5  6]]

 [[ 7  8  9]
  [10 11 12]]]
(2, 2, 3)
#######################################

修改数组的形状:

import numpy as np

t4 = np.array(range(12))
print(t4)
print(t4.reshape((3,4)))
print("#######################################")
t5 = np.arange(24).reshape((2,3,4))
print(t5)
print(t5.reshape((4,6)))
print(t5.flatten()) # 展开成一维数组

运行结果:

[ 0  1  2  3  4  5  6  7  8  9 10 11]
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
#######################################
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

数组和数的计算

广播原则

在这里插入图片描述

可以把维度指的是shape所对应的数字个数。

shape为(3,3,3)的数组能够和(3,2)的数组进行计算么?

不可以

shape为(3,3,2)的数组能够和(3,2)的数组进行计算么?、

可以

所以假设有两个数组,第一个的维度是(x_1, y_1, z_1),另一个数组的维度是(x_2, y_2, z_2),要判断这两个数组能不能进行计算,可以用如下方法来判断:

if z_1 == z_2 or z_1 == 1 or z_2 == 1:
    if y_1 == y_2 or y_1 == 1 or y_2 == 1:
        if x_1 == x_2 or x_1 == 1 or x_2 == 1:
            可以运算
        else:
            不可以运算
    else:
        不可以运算
else:
    不可以运算

这里需要注意:(3,3,2)和(3,2)是可以运算的,因为对于二维数组(3,2)也可以表示为(1,3,2),套用上述的规则是完全适用的,同理:(4,2,5,4)和(2,1,4)也是可以进行运算的。

轴(axis)

在numpy中可以理解为方向,使用0,1,2…数字表示,对于一个一维数组,只有一个0轴,对于2维数组(shape(2,2)),有0轴和1轴,对于三维数组(shape(2,2, 3)),有0,1,2轴。

有了轴的概念之后,我们计算会更加方便,比如计算一个2维数组的平均值,必须指定是计算哪个方向上面的数字的平均值。

回顾np.arange(0,10).reshape((2,5)),reshpe中2表示0轴长度(包含数据的条数)为2,1轴长度为5,2X5一共10个数据。

二维数组的轴

在这里插入图片描述

三维数组的轴

在这里插入图片描述

numpy读取本地数据

读取文件:CSV:Comma-Separated Value,逗号分隔值文件

显示:表格状态

源文件:换行和逗号分隔行列的格式化文本,每一行的数据表示一条记录

由于csv便于展示,读取和写入,所以很多地方也是用csv的格式存储和传输中小型的数据,为了方便教学,我们会经常操作csv格式的文件,但是操作数据库中的数据也是很容易的实现的。

np.loadtxt(fname,dtype=np.float,delimiter=None,skiprows=0,usecols=None,unpack=False)

在这里插入图片描述

示例:现在这里有一个英国和美国各自youtube1000多个视频的点击,喜欢,不喜欢,评论数量([“views”,“likes”,“dislikes”,“comment_total”])的csv,运用刚刚所学习的只是,我们尝试来对其进行操作。

import numpy as np

us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"

t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t2 = np.loadtxt(us_file_path,delimiter=",",dtype="int")

print(t1)
print("*"*100)
print(t2)

运行结果:

[[4394029 7860119 5845909 ...  142463 2162240  515000]
 [ 320053  185853  576597 ...    4231   41032   34727]
 [   5931   26679   39774 ...     148    1384     195]
 [  46245       0  170708 ...     279    4737    4722]]
****************************************************************************************************
[[4394029  320053    5931   46245]
 [7860119  185853   26679       0]
 [5845909  576597   39774  170708]
 ...
 [ 142463    4231     148     279]
 [2162240   41032    1384    4737]
 [ 515000   34727     195    4722]]

在这里插入图片描述

numpy中的转置

常用数组转置:

  • self.transpose();
  • self.T;
  • self.swapaxes(1.0):交换0和1轴。

在这里插入图片描述
在这里插入图片描述

numpy索引和切片

操作很简单,和python中列表的操作一样。

#取行
print(t2[2]) #第3行
print("*"*100)

#取连续的多行
print(t2[2:]) # 第3行至最后一行
print("*"*100)

#取不连续的多行
print(t2[[2,8,10]]) #第3、9、11行

#加冒号
print(t2[1,:]) #第2行
print(t2[2:,:]) # 第3行至最后一行
print(t2[2:,3]) #第4列的第3行至最后一行
print(t2[2:,:3]) #第3行至最后一行的第1列至第3列
print(t2[[2,8,10],:]) #第3、9、11行

#取列
print(t2[:,0]) #第1列

#取连续的多列
print(t2[:,2:]) #第3列至最后一列
print(t2[:,2::2]) #第3列至最后一列,步长为2

#取不连续的多列
print(t2[:,[0,2]]) #第1列和第三列

#取特定值,取第3行,第4列的值
a = t2[2,3]
print(a)
print(type(a))

# 取多行和多列,取第3行到第5行,第2列到第4列的结果
# 取的是行和列交叉点的位置
b = t2[2:5,1:4] #索引包头不包尾
print(b)

# 取多个不相邻的点
# 选出来的结果是(0,0) (2,1) (2,3)位置的值
c = t2[[0,2,2],[0,1,3]]
print(c)

numpy中数值的修改

import numpy as np
a = np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10],[10,11,12,13]])
print(a)
print("*"*100)
a[:,1:3] = 0
print(a)
print("*"*100)

#布尔索引
print(a==0)
a[a==0] = 1
print(a)
print("*"*100)

#三元运算符
a = np.where(a>5,5,2) #大于5的数变成5,其他的变成2
print(a)
print("*"*100)

#numpy中的clip(裁剪)
a = a.clip(3,4) #比3小的变成3,比4大的变成4
print(a)

运行结果:

[[ 1  2  3  4]
 [ 4  5  6  7]
 [ 7  8  9 10]
 [10 11 12 13]]
****************************************************************************************************
[[ 1  0  0  4]
 [ 4  0  0  7]
 [ 7  0  0 10]
 [10  0  0 13]]
****************************************************************************************************
[[False  True  True False]
 [False  True  True False]
 [False  True  True False]
 [False  True  True False]]
[[ 1  1  1  4]
 [ 4  1  1  7]
 [ 7  1  1 10]
 [10  1  1 13]]
****************************************************************************************************
[[2 2 2 2]
 [2 2 2 5]
 [5 2 2 5]
 [5 2 2 5]]
****************************************************************************************************
[[3 3 3 3]
 [3 3 3 4]
 [4 3 3 4]
 [4 3 3 4]]

numpy中的nan和inf

nan(NAN,Nan):not a number表示不是一个数字。

当我们读取本地的文件为float的时候,如果有缺失,就会出现nan
。当做了一个不合适的计算的时候(比如无穷大(inf)减去无穷大),就会出现nan。

nf(-inf,inf):infinity,inf表示正无穷,-inf表示负无穷

比如一个数字除以0,(python中直接会报错,numpy中是一个inf或者-inf)

nan和inf的type类型都是float型

numpy中的nan的注意点:

  • 两个nan是不相等的;
  • np.count_nonzero(t!=t),可以统计t中nan的个数,因为t!=t返回bool值,利用布尔索引实现。
  • np.isnan(t)与t!=t同;
  • nan和任何值计算都是nan

在一组数据中单纯的把nan替换为0,替换之前的平均值如果大于0,替换之后的均值肯定会变小,所以更一般的方式是把缺失的数值替换为均值(中值)或者是直接删除有缺失值的一行

numpy中常用统计函数

  • 求和:t.sum(axis=None)
  • 均值:t.mean(a,axis=None)
  • 受离群点的影响较大
  • 中值:np.median(t,axis=None)
  • 最大值:t.max(axis=None)
  • 最小值:t.min(axis=None)
  • 极差:np.ptp(t,axis=None) 即最大值和最小值只差
  • 标准差:t.std(axis=None)

在这里插入图片描述

标准差是一组数据平均值分散程度的一种度量。一个较大的标准差,代表大部分数值和其平均值之间差异较大;一个较小的标准差,代表这些数值较接近平均值
反映出数据的波动稳定情况,越大表示波动越大,越不稳定。

用数组每列除nan外所有值的平均值代替nan:

import numpy as np

def fill_ndarray(t1):
    for i in range(t1.shape[1]):  #遍历每一列
        temp_col = t1[:,i]  #当前的一列
        nan_num = np.count_nonzero(temp_col!=temp_col)#利用np.count_nonzero统计nan个数
        if nan_num !=0: #不为0,说明当前这一列中有nan
            temp_not_nan_col = temp_col[temp_col==temp_col] #当前一列不为nan的array

            # 选中当前为nan的位置,把值赋值为当前列不为nan的均值
            temp_col[np.isnan(temp_col)] = temp_not_nan_col.mean()
    return t1

if __name__ == '__main__':
    t1 = np.arange(24).reshape((4, 6)).astype("float")
    t1[1, 2:] = np.nan
    print(t1)
	print("*"*100)
    t1 = fill_ndarray(t1)
    print(t1)

运行结果:

[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7. nan nan nan nan]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]]
****************************************************************************************************
[[ 0.  1.  2.  3.  4.  5.]
 [ 6.  7. 12. 13. 14. 15.]
 [12. 13. 14. 15. 16. 17.]
 [18. 19. 20. 21. 22. 23.]]

结合matplotlib把数据呈现出来

1.英国和美国各自youtube1000的数据结合之前的matplotlib绘制出各自的评论数量的直方图

import numpy as np
from matplotlib import  pyplot as plt

us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"

# t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t_us = np.loadtxt(us_file_path,delimiter=",",dtype="int")

#取评论的数据
t_us_comments = t_us[:,-1]

#选择比5000小的数据
t_us_comments = t_us_comments[t_us_comments<=5000]

print(t_us_comments.max(),t_us_comments.min())

d = 50

bin_nums = (t_us_comments.max()-t_us_comments.min())//d

#绘图
plt.figure(figsize=(20,8),dpi=80)

plt.hist(t_us_comments,bin_nums)


plt.show()

运行结果:
4995 0

在这里插入图片描述

2.希望了解英国的youtube中视频的评论数和喜欢数的关系,应该如何绘制改图

import numpy as np
from matplotlib import  pyplot as plt

us_file_path = "./youtube_video_data/US_video_data_numbers.csv"
uk_file_path = "./youtube_video_data/GB_video_data_numbers.csv"

# t1 = np.loadtxt(us_file_path,delimiter=",",dtype="int",unpack=True)
t_uk = np.loadtxt(uk_file_path,delimiter=",",dtype="int")

#选择喜欢书比50万小的数据
t_uk = t_uk[t_uk[:,1]<=500000]

t_uk_comment = t_uk[:,-1]
t_uk_like = t_uk[:,1]



plt.figure(figsize=(20,8),dpi=80)
plt.scatter(t_uk_like,t_uk_comment)

plt.show()

运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值