numpy学习(一)

本文详细介绍了numpy库的基本操作,包括创建数组、指定数据类型、数组形状、转置、索引切片以及数组计算。还讨论了如何处理小数、调整数据类型、数组的统计函数和处理nan、inf的情况。此外,文章还涵盖了数组拼接、行列交换以及使用numpy进行随机数生成等实用功能。
摘要由CSDN通过智能技术生成

numpy可以帮助我们处理数值型的数据,注意,是数值型
用于处理数组(或者叫做矩阵)

创建数组(或矩阵)

可以先简单的通过列表创建数组

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

来看看输出了什么

在这里插入图片描述

打印出了一个像列表的数据,但是中间没有逗号~

还有其他一些简单的创建方式

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

我们可以发现t2和t3其实是一样的,类型也都是和t1一样的
在这里插入图片描述
当然np.arange()也可以像range()一样取步长

数组元素的数据类型

我们并没有指定这些元素的数据类型

我们来看看它们里面元素的数据类型(因电脑位数不同而会有所不同)

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

# 查看数组元素的数据类型
print(t3.dtype)

这里打印出是int32位的
在这里插入图片描述
还有其他更多的数据类型
在这里插入图片描述

在实际形况中,我们可以指定数组里面的数据类型,可以达到节省空间的目的

创建时指定数据类型

array()函数里面有个dtype参数可以指定元素的数据类型

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

# 查看数组元素的数据类型
print(t3.dtype)

print("*"*50)

# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)

在这里插入图片描述
好像这个bool类型的蛮有趣的,我们来看看它是怎么样的

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

# 查看数组元素的数据类型
print(t3.dtype)

print("*"*50)

# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)

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

打印出来效果是这样的
在这里插入图片描述

调整数据类型

需要astype()函数,里面传入调整后的数据类型就好了

import numpy as np

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

# 查看数组元素的数据类型
print(t3.dtype)

print("*"*50)

# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)

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

t6 = t5.astype('int8')
print(t6)
print(t6.dtype)

在这里插入图片描述

numpy中的小数

np.round()可以帮助取几位小数

import numpy as np
import random

t1 = np.array([1,2,3])
print(t1)
print(type(t1))

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

t3 = np.arange(10)
print(t3)

# 查看数组元素的数据类型
print(t3.dtype)

print("*"*50)

# 指定数据类型
t4 = np.array(range(1,4),dtype='float32')
print(t4)
print(t4.dtype)

# numpy中的bool类型
t5 = np.array([1,1,0,1,0,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)

t8 = np.round(t7,2)
print(t8)

在这里插入图片描述

数组的形状

什么是数组的形状?
先来看个例子

import numpy as np

t1 = np.arange(12)
print(t1)
print(t1.shape)

t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)

在这里插入图片描述
原来数组的形状就是它是描述它的纬度

一维的数组打印出来只有一个数字,二维的两个数组打印出来有两个数字

那三维的是不是三个呢,我们来看看

import numpy as np

# 一维
t1 = np.arange(12)
print(t1)
print(t1.shape)

# 二维
t2 = np.array([[1,2,3],[4,5,6]])
print(t2)
print(t2.shape)

# 三维
t3 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(t3)
print(t3.shape)

在这里插入图片描述

三维打印出来的(2, 2, 3), 第一个2表示块数,相当于是空间坐标的Z轴,后面的(2,3)就是平面的2行3列

调整数组的纬度

我们可以将一维的变成2维的,也可以将2维的变成一维的

用到了reshape()函数

import numpy as np

t4 = np.array(range(12))
print(t4)

t4 = t4.reshape(3,4)
print(t4)

当然转换的要求要保证前后数量一致,不然就报错
在这里插入图片描述


一维转三维

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
print(t5)

在这里插入图片描述


三维的转二维的

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
print(t5)
print(t5.reshape(4,6))

转换的过程大概是三维的先压平成一维的,然后从一维的变成二维的
在这里插入图片描述


二维边一维

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)

t7 = t6.reshape(24,)
print(t7)

在这里插入图片描述

想一想,为什么不是t6.reshape(1,24)

我们来打印一下结果你就会发现它其实是二维的

在这里插入图片描述


如果有一个二维数组非常大,我想把它变成一维,是不是要知道元素的个数

在二维数组中,shape[0]表示有多少行,shape[1]表示有多少列

那么我们可以这样

t6 = t5.reshape(t5.shape[0]*t5.shape[1],)

还有一种简便的方法变成一维

有个函数叫做flatten(),碾平的意思

这种方式不需要传入元素的个数

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)

t7 = t6.flatten()
print(t7)

在这里插入图片描述

数组的计算

一个数组和一个数计算,所有的元素都会与它运算

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)

t7 = t6 + 1
print(t7)

在这里插入图片描述

如果除于0呢,看看会不会出问题

import numpy as np

t5 = np.arange(24).reshape((2,3,4))
t6 = t5.reshape(4,6)
print(t6)

t7 = t6/0
print(t7)

程序只是报了warning,还是可以显示的,只是这结果不对劲呀

nan意思not a number, 它不是一个数,可以是其他东西,比如字符串,香蕉苹果啥的

inf意思是无穷大的意思,还有-inf是无穷小
在这里插入图片描述


一个数组和一个相同形状的数组运算,对应位置独立运算,这个很好理解


如果是不同纬度的数组相互计算,如果存在某个维度上一致,那么是可以计算的

我们来看看

import numpy as np

t1 = np.arange(6)

t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)

在这里插入图片描述
那么这两个数组可以计算吗?

是可以的,因为在行的方向上的纬度是一样的

import numpy as np

t1 = np.arange(6)

t2 = np.array([np.arange(6),np.arange(6,12),np.arange(12,18)])
print(t1)
print(t2)

print(t1+t2)

在这里插入图片描述

如果是列方向纬度一致,也是一样的

三维的和二维的计算也是同一个道理

在numpy中可以理解为方向,用0,1,2数字表示

对于一个一维数组,只有一个0轴

二维数组,有0轴和1轴,0轴表示行方向,1轴表示列方向

三维数组,有0,1,2轴,0表示高度(Z轴),1表示行方向,2表示列方向

转置

numpy中转置有多种方法,这里介绍常用的两种方法

第一种是transpose()

第二种是属性T

import numpy as np

t1 = np.arange(12).reshape(3,4)

print(t1)
print(t1.transpose())
print(t1.T)

在这里插入图片描述

索引和切片

numpy中索引从0开始的

取某一行,注意取出来的是一维的

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第三行
print(t1[2])

在这里插入图片描述

取连续的多行

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第2: 3 行
print(t1[1:3])

在这里插入图片描述


取不连续的多行
都加了一个方括号

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第2行和第4行
print(t1[[1,3]])

在这里插入图片描述


取某一列,注意选出来的是一维的

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

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

在这里插入图片描述


取连续的几列

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第2:4列
print(t1[:,1:4])

在这里插入图片描述


取不连续的多列

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第1列和第3列
print(t1[:,[0,2]])

在这里插入图片描述


取多行多列

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

# 取第3行第4列的值,虽然是一个数但类型要注意
a = t1[2,3]
print(a)
print(type(a))

# 取第2:4行,第3到第6列
print(t1[1:4,2:6])

# 取多个不相邻的点,有些特殊
# 取(0,2),(3,1)值
print(t1[[0,3],[2,1]])

在这里插入图片描述

对数组的修改

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

t1[:,1:3] = 0
print(t1)

在这里插入图片描述

如果要把数组中小于10的修改为10怎么写?

先看下面程序

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

print(t1<10)

在这里插入图片描述

可以看出那些是小于10的,这就是很常用的bool索引

如果要把数组中小于10的修改成10,那么这就很简单了

t1[t1<10] = 10

如果想把小于10的改为0,大于10的改为10

按照上面的方法,我们要写两行

这里介绍一个where()函数,一行就能解决

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

print(np.where(t1<10,0,10))

在这里插入图片描述


问题升级

如果我想把小于10的改为10,大于20的改为20呢?

当然bool索引可以做,也是写两行

这里介绍一个clip()裁剪函数

import numpy as np

t1 = np.arange(24).reshape(4,6)
print(t1)

print("*"*50)

print(t1.clip(10,18))

在这里插入图片描述

nan和inf

nan就是not a number,表示不是一个数字

numpy中出现nan的情况:

当我们读取本地文件为float的时候,如果有缺少,就会出现nan

当做了一个不合适的计算的时候,比如( 无穷大(inf)减去无穷大)

inf表示正无穷,-inf表示负无穷

什么时候会出现inf:

当一个数字处于0 (python中会直接报错,而numpy会出现inf)


在numpy中如何指定一个数为nan和inf

import numpy as np

a = np.nan
print(a)
print(type(a))

b = np.inf
print(b)
print(type(b))

发现它们都是float类型

在这里插入图片描述


numpy中nan的注意点

两个nan是不想等的

import numpy as np

print(np.nan == np.nan)

在这里插入图片描述

这个性质有一些特殊用途

比如,可以判断数组中nan的个数

先介绍count_nonzero()数组是统计非0的个数

import numpy as np

a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)

print(a!=a)

# 统计a中nan的个数
print(np.count_nonzero(a!=a))

在这里插入图片描述
还可以这样统计nan的个数

import numpy as np

a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)

print(np.isnan(a))

# 统计a中nan的个数
print(np.count_nonzero(np.isnan(a)))

在这里插入图片描述

这样可以把为nan的地方换成别的值,比如0

a[np.isnan(a)] = 0

nan和任意值运算都为nan

这里介绍一个np.sum()函数,统计和的

import numpy as np

a = np.arange(12).reshape(3,4).astype('float')
a[2,3] = np.nan
print(a)

# 计算数组a的和
print(np.sum(a))

# 计算行方向上的值
print(np.sum(a,axis=0))

在这里插入图片描述


因为nan不能参与计算,那么一般都是把nan替换次别的值

有些时候单纯的替换成0是不合适的

更一般是替换成均值(中值),或者直接删去

那么问题来了

怎么计算一组数据的中值或均值?

如何删除有缺失的那一行(列) ?【在pandas中介绍】

numpy中常用的统计函数

在这里插入图片描述

将数组中nan填充为均值

import numpy as np

def fill_ndarray(t1):
    '''
    把数组中有nan的地方填充为均值
    :param t1: 原始的二维数组
    :return: 填充之后的数组
    '''
    # 遍历所有列
    for i in range(t1.shape[1]):
        # 当前列
        cur_col = t1[:,i]
        # 当前列中nan的个数
        num_not_nan = np.count_nonzero(cur_col!=cur_col)
        # 如果当前列有nan
        if num_not_nan != 0:
            # 当前列不为nan的ndarray
            array_not_nan = cur_col[cur_col==cur_col]
            # 把nan的位置赋值为均值
            cur_col[np.isnan(cur_col)] = array_not_nan.mean()
    return t1

if __name__ == '__main__':
    # 创建一个二维数组,类型为float
    t1 = np.arange(12).reshape(3,4).astype('float')
    # 将t1数组里面部分值赋值为nan
    t1[1,2:] = np.nan
    print(t1)
    t1 = fill_ndarray(t1)
    print(t1)

在这里插入图片描述

数组拼接

竖直拼接np.vstack()

水平拼接np.hstack()

注意传入的是一个元组,就是有两层括号

import numpy as np

t1 = np.arange(10).reshape(2,5)
t2 = np.arange(10,20).reshape(2,5)

print(t1)
print(t2)

# 竖直拼接np.hstack((t1,t2))
t3 = np.vstack((t1,t2))
print(t3)

# 水平拼接
print(np.hstack((t1,t2)))

在这里插入图片描述

数组的行列交换

import numpy as np

t1 = np.arange(12).reshape(3,4)
print(t1)

# 第2行和第3行交换
t1[[1,2],:] = t1[[2,1],:]
print(t1)

#第1列和第3列交换
t1[:,[0,2]] = t1[:,[2,0]]
print(t1)

在这里插入图片描述

numpy更多好用的方法

创建一个全0的数组 np.zeros((3,4))
创建一个全1的数组 np.ones((3,4))
创建一个对角线为1的方阵 np.eye(5)

获取数组最大值,最小值的位置,可以指定方向

import numpy as np

t = np.array([[3,5,1,0],[6,3,8,9]])

print(t)
print(t.argmax())
print(t.argmax(axis=1))
print(t.argmin(axis=0))

在这里插入图片描述

随机数

在这里插入图片描述

numpy的注意点copy和view

  1. a=b完全不复制,a和b相互影响,即a和b共享一块内存
  2. a = b[:] ,视图操作,也是完全不复制
  3. a = b.copy(), 深拷贝,a和b互不影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值