Python 数据分析之Numpy学习(一)

Python 数据分析之Numpy学习(一)

一、Numpy的引入

1.1 矩阵/向量的按位运算

需求:矩阵的按位相加
[0,1,4] + [0,1,8] = [0,2,12]

1.1.1 利用python实现矩阵/向量的按位运算

# 1.通过列表实现
list1 = [0, 1, 4]
list2 = [0, 1, 8]
# 列表使用 + 操作是将两个列表进行连接,不是算术运算
list1 + list2# 结果:
[0, 1, 4, 0, 1, 8]
# 使用循环 + append实现
list_sum = []# 通过索引进行遍历
for i in range(len(list1)):# 通过索引同时遍历list1和list2,方便从2个列表中同时提取数据list_sum.append(list1[i] + list2[i])list_sum
[0, 2, 12]
# 2.通过推导式实现
[list1[i] + list2[i] for i in range(len(list1))]
[0, 2, 12]

对上述的按位相加运算进行扩充:
扩充到两个n位的列表进行按位相加操作,第一个列表的元素是0到n-1的平方,第二个列表的元素是0到n-1的三次方
[0, 1, 4, …] + [0, 1, 8, …] = [0, 2, 12, …]

# 构建一个函数,用来生成 0 到 n-1 的 m 次方列表
def create_list(n,m):    # n是列表中的元素数量,m是所求次方return [item ** m for item in range(n)]
# 测试构建的函数
# 生成 10 个元素的平方
create_list(10, 2)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 生成 5 个元素的立方
create_list(5, 3)
[0, 1, 8, 27, 64]
# 构建函数用来实现 n 个元素的平方和立方的按位相加
def pySum(n):  # n是列表的元素数量list_1 = create_list(n, 2)list_2 = create_list(n, 3)return [list_1[i] + list_2[i] for i in range(n)]
# 测试Pysum函数
pySum(5)
[0, 2, 12, 36, 80]
pySum(10)
[0, 2, 12, 36, 80, 150, 252, 392, 576, 810]

1.1.2 用numpy实现矩阵/向量的按位运算

# 载入库
import numpy as np
# 构建用Numpy实现按位相加的函数
def npSum(n):a = np.arange(n) ** 2b = np.arange(n) ** 3return a + b
# 测试npSum函数
npSum(5)
array([ 0,  2, 12, 36, 80])
npSum(10)
array([  0,   2,  12,  36,  80, 150, 252, 392, 576, 810])

1.1.3 numpy与原生python在科学计算上的对比

# (1)溢出的问题
# python实现,正常
pySum(100000)[-3:]
[999920002099982, 999950000799996, 999980000100000]
# numpy实现,出现了溢出问题
npSum(100000)[-3:]
array([ 75983630,   9912572, -55558496])

在Windows操作系统下,用numpy创建的整数类型的数组默认采用的是 np.int32 数据类型,该数据类型能容纳的最大数值是2^31-1,当我们要计算的数值超过该数值,计算结果就会出错,解决方法是采用更大的数据类型 np.int64。

# 修改按位相加函数中的数组的数据类型改为 np.int64
def npSum64(n):a = np.arange(n, dtype = np.int64) ** 2b = np.arange(n, dtype = np.int64) ** 3return a + b
# 测试npSum64函数是否还会出现溢出问题,结果是输出正确结果
npSum64(100000)[-3:]
array([999920002099982, 999950000799996, 999980000100000], dtype=int64)
# (2)代码简洁程度:numpy代码比python代码实现按位相加要更简洁
# (3) numpy与原生python在科学计算上的性能差异
# %timeit    #精确计算其后代码执行的时间长度,是jupyter上的一个特殊的命令(魔法命令)
%timeit pySum(100000)
36.4 ms ± 922 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit npSum64(100000)
1.03 ms ± 11.6 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

两者执行相差:35.7 / 1,相差三十多倍,随着计算的复杂程度的提高,numpy节约的时间越多

总结:从上述情况来看,在实现科学计算上,不管是从代码的简洁程度还是执行效率上来看,numpy的表现较好

1.2 Numpy的简介

NumPy是一个开源的Python科学计算库,它包括:

  • 一个强大的N维数组对象ndrray;
  • 比较成熟的函数库;
  • 用于整合C/C++和Fortran代码的工具包;
  • 实用的线性代数、傅里叶变换和随机数生成函数

NumPy支持高维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
Numpy成为事实上的Scipy、Pandas、Scikit-Learn、Tensorflow、PaddlePaddle等框架的"通用底层语言"。
Numpy的array和Python的List的一个区别,是它元素必须都是同一种数据类型,比如都是数字int类型,这也是Numpy高性能的一个原因。

1.2.1 Python的缺点和Numpy的改进

标准Python中用列表(list)可以用来当作数组使用,但是列表中所保存的是对象(任意对象)的指针。对于数值运算来说这种结构比较浪费内存和CPU计算时间。
NumPy提供了以下对象,解决标准Python的不足:
①ndarray:N维数组(简称数组)对象,存储单一数据类型的N维数组
②ufunc:通用函数对象,对数组进行处理的函数。

1.2.2 Ndarray的理解

NumPy中的ndarray是一个多维数组对象,它是一个快速而灵活的大数据集容器,它由两部分组成:
①实际的数据;
②描述这些数据的元数据。(相当于形状)
大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据。

image.png

形状:描述数组的元数据
image.png

二、创建Ndarray

2.1 一维数组的创建

2.1.1 np.array创建数组

# ?np.array

array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None)

  • object:用来转换为数组的对象,一般是容器/序列类对象
  • dtype:数据类型,一般不专门设置,因为np会自动识别对象的数据类型

注意:array是个函数,后面要写成()

# 1.列表转数组
arr1 = np.array([1, 2, 3, 4, 5])
arr1   # 直接写是访问对象,直接访问对象是用逗号隔开
array([1, 2, 3, 4, 5])
# 用print输出,输出结果用空格隔开
print(arr1)
[1 2 3 4 5]

列表直接访问和用print输出没有区别,都是用逗号隔开,但是数组不一样

# 观察arr1的数据类型
type(arr1)     # numpy.ndarray
numpy.ndarray
# 2.元组转数组
np.array((1, 2, 3))
array([1, 2, 3])
# 3.range转数组
np.array(range(10))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 4.字符串转数组,得到的不是字符,而是一个完整的字符串
np.array('hello')
array('hello', dtype='<U5')
# 如果要得到字符串中每个字符构成的数组,先将字符串转为列表,然后将列表转换为数组
np.array(list('hello'))
array(['h', 'e', 'l', 'l', 'o'], dtype='<U1')

2.1.2 数组相关概念

  • 数组的维度
    ndarray.ndim - 返回数组维度的数量(轴),返回的是1,2……,表示一维、二维……
arr1.ndim
# 返回数字1,说明arr1是一个一维数组(数组的轴的数量是1)
1
  • 数组的形状
    ndarray.shape - 返回数组的形状,即数组在每个维度(轴)上的元素数量,结果是一个元组
arr1.shape
# 返回一个元组,说明arr1是一个一维数组(只有第一个元素有值),该维度上有5个元素
(5,)
type(arr1.shape)   # 返回的对象是元组类型
tuple
  • 数组的数据类型
    ndarray.dtype - 返回数组的数据类型

type和dtype的区别:type得到的是对象的数据类型,dtype得到的是对象中的元素的数据类型

type(arr1)   # 返回的是arr1对象的数据类型
numpy.ndarray
arr1.dtype   # arr1的数据类型是np.int32
dtype('int32')
# 数组的数据类型会根据转换的对象自动设定,数组的数据类型由数组中兼容性最强的数据决定
arr2 = np.array([1,2,3,4.5,6])
arr2
array([1. , 2. , 3. , 4.5, 6. ])
arr2.dtype
dtype('float64')

2.2 等差数组的创建

2.2.1 np.arange创建

# ?np.arange

arange([start,] stop[, step,], dtype=None, *, like=None)
其中start/stop/step都可以使用浮点数,最终返回的是左闭右开的区间

arange和range的区别:range中的三个参数必须是整数,而arange中的三个参数可以是整数,也可以是浮点数

np.array(range(9))
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
# np.array(range(0.1,1.1,0.1))   # 报错
# TypeError: 'float' object cannot be interpreted as an integer
arr3 = np.arange(0.1,1.1,0.1)
arr3
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

arange返回的是左闭右开的区间,如果要对称的,就需要自己计算stop和step的值

# 例如,要返回-1,1,0.05
np.arange(-1,1.05,0.05)
array([-1.0000000e+00, -9.5000000e-01, -9.0000000e-01, -8.5000000e-01,-8.0000000e-01, -7.5000000e-01, -7.0000000e-01, -6.5000000e-01,-6.0000000e-01, -5.5000000e-01, -5.0000000e-01, -4.5000000e-01,-4.0000000e-01, -3.5000000e-01, -3.0000000e-01, -2.5000000e-01,-2.0000000e-01, -1.5000000e-01, -1.0000000e-01, -5.0000000e-02,8.8817842e-16,  5.0000000e-02,  1.0000000e-01,  1.5000000e-01,2.0000000e-01,  2.5000000e-01,  3.0000000e-01,  3.5000000e-01,4.0000000e-01,  4.5000000e-01,  5.0000000e-01,  5.5000000e-01,6.0000000e-01,  6.5000000e-01,  7.0000000e-01,  7.5000000e-01,8.0000000e-01,  8.5000000e-01,  9.0000000e-01,  9.5000000e-01,1.0000000e+00])
# 如果修改了步长,就不对称了
np.arange(-1,1.05,0.03)
array([-1.  , -0.97, -0.94, -0.91, -0.88, -0.85, -0.82, -0.79, -0.76,-0.73, -0.7 , -0.67, -0.64, -0.61, -0.58, -0.55, -0.52, -0.49,-0.46, -0.43, -0.4 , -0.37, -0.34, -0.31, -0.28, -0.25, -0.22,-0.19, -0.16, -0.13, -0.1 , -0.07, -0.04, -0.01,  0.02,  0.05,0.08,  0.11,  0.14,  0.17,  0.2 ,  0.23,  0.26,  0.29,  0.32,0.35,  0.38,  0.41,  0.44,  0.47,  0.5 ,  0.53,  0.56,  0.59,0.62,  0.65,  0.68,  0.71,  0.74,  0.77,  0.8 ,  0.83,  0.86,0.89,  0.92,  0.95,  0.98,  1.01,  1.04])

2.2.2 np.linspace创建

np.linspace用于创建等差数组,可以得到闭区间s=0,
)

np.linspace(start,    # 起始值stop,     # 结束值num=50,    # 数据的分割点数endpoint=True,   # True,闭区间retstep=False,dtype=None,axis=0,
)
返回一个将指定的区间划分为若干段的数组,返回结果是一个闭区间的等差数组
# ?np.linspace
# -1, 1
arr4 = np.linspace(-1, 1, 20)
arr4
array([-1.        , -0.89473684, -0.78947368, -0.68421053, -0.57894737,-0.47368421, -0.36842105, -0.26315789, -0.15789474, -0.05263158,0.05263158,  0.15789474,  0.26315789,  0.36842105,  0.47368421,0.57894737,  0.68421053,  0.78947368,  0.89473684,  1.        ])
# 每段的距离
(1-(-1))/(20-1)
0.10526315789473684
-0.89473684 - (-1)
0.10526316000000002
# 如果希望每段的距离都是0.1
np.linspace(-1,1,21)
array([-1. , -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1,  0. ,0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])

在NumPy中,linspace 函数用于创建一个特定范围内的均匀间隔的数组。但是,NumPy 并没有提供直接的功能来获取 linspace 数组的分割点数量。不过,你可以通过计算数组的长度并除以(数组元素总数 - 1)来大致估算分割点的数量。

2.3 二维数组的创建

2.3.1 np.array创建

利用嵌套array的方式进行创建,语法:np.array(嵌套的iterable)

arr5 = np.array([np.array([1, 2, 3]),np.array([4, 5, 6]),np.array([7, 8, 9]),
])
arr5
array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])

如何看创建的数组是几维数组:

  • 通过看array()里面[]的数量
  • 通过ndarray.ndim进行查看
  • 通过ndarray.shape进行观察
arr5.ndim
2
arr5.shape
# 数组的维度是二维,第一个维度(行)上的元素数量是3个,第二个维度(列)上的元素数量是3个
(3, 3)
# 也可以使用嵌套容器
arr6 = np.array([[1,2,3,4],(5,6,7,8),range(9,13)]
)
arr6
array([[ 1,  2,  3,  4],[ 5,  6,  7,  8],[ 9, 10, 11, 12]])
arr6.ndim
2
arr6.shape
(3, 4)

2.3.2 用占位方法创建数组

通常,数组的元素最初是未知的,但它的大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组。这就减少了数组增长的必要,因为数组增长的操作很麻烦。

2.3.2.1 np.zeros/np.zeros_like 全0数组

np.zeros语法:np.zeros(shape, dtype=float, order='C', *, like=None)
(1)shape:维度信息,整数(一维数组),多维需要放到元组中
(2)dtype:数据类型,默认是np.float64
(3)like:用来进行参考的类数组对象,如果设置,则生成的数组的形状和数据类型会和参考的类数组对象一致

np.zeros((3,6))
array([[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.]])

np.zeros_like语法:np.zeros_like(a, dtype=None, order='K', subok=True, shape=None)
(1)a:用来参考的类数组对象
(2)shape:维度信息,整数(一维数组),多维需要放到元组中
(3)dtype:数据类型,默认是np.float64
返回一个形状和数据类型和参考对象一致的全0数组

# ?np.zeros_like
# 当设置成python数据类型是,np会自动转换成numpy所对应的数据类型
a1x = np.zeros((3,3), dtype = int)
a1x
array([[0, 0, 0],[0, 0, 0],[0, 0, 0]])
a2 = np.zeros_like(arr6)
a2
array([[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]])
2.3.2.2 np.ones/np.ones_like 全1数组

np.ones语法:np.ones(shape, dtype=None, order='C', *, like=None)
(1)shape:维度信息,整数(一维数组),多维需要放到元组中
(2)dtype:数据类型,默认是np.float64
(3)like:用来进行参考的类数组对象,如果设置,则生成的数组的形状和数据类型会和参考的类数组对象一致

a3 = np.ones((5,3))
a3
array([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]])
a4 = np.ones((5,3), dtype =int)
a4
array([[1, 1, 1],[1, 1, 1],[1, 1, 1],[1, 1, 1],[1, 1, 1]])

np.ones_like语法:np.ones_like(a, dtype=None, order='K', subok=True, shape=None)
(1)a:用来参考的类数组对象
(2)shape:维度信息,整数(一维数组),多维需要放到元组中
(3)dtype:数据类型,默认是np.float64
返回一个形状和数据类型和参考对象一致的全1数组

# ?np.ones_like
a6 = np.ones_like(arr6)
a6
array([[1, 1, 1, 1],[1, 1, 1, 1],[1, 1, 1, 1]])
2.3.2.3 np.full/np.full_like全填充数组

np.full语法:np.full(shape, fill_value, dtype=None, order='C', *, like=None)
(1)shape : 维度信息,多维需要放到元组中
(2)fill_value : 填充的内容,可以是单个的值(不一定是数值),或者类数组对象
(3)dtype : 数据类型 根据fill_value的值决定

# ?np.full_like

np.full_like语法:np.full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None)
(1)a:用来参考的类数组对象
(2)fill_value : 填充的内容,可以是单个的值(不一定是数值),或者类数组对象
(3)dtype:数据类型,根据fill_value的值决定
(4)shape:维度信息,整数(一维数组),多维需要放到元组中
返回一个形状和数据类型跟参考对象一致的用指定值填充的数组

a7 = np.full((4,5),fill_value=7)
a7
# fill_value同时决定了填充的内容和数组的数据类型
array([[7, 7, 7, 7, 7],[7, 7, 7, 7, 7],[7, 7, 7, 7, 7],[7, 7, 7, 7, 7]])
a8 = np.full((4,6), fill_value='python')
a8
array([['python', 'python', 'python', 'python', 'python', 'python'],['python', 'python', 'python', 'python', 'python', 'python'],['python', 'python', 'python', 'python', 'python', 'python'],['python', 'python', 'python', 'python', 'python', 'python']],dtype='<U6')
np.full((5,5), fill_value = range(5))
# 对每一行的内容用0~4的序列进行填充,用类数组对象在填充时要注意形状的匹配
array([[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4],[0, 1, 2, 3, 4]])
# np.full((5,5), fill_value = [1,2])
# ValueError: could not broadcast input array from shape (2,) into shape (5,5)
# 注意fill_value的内容形状与full的内容形状要匹配,否则会报错
# 布尔数组
np.full((4,5),True)
array([[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True],[ True,  True,  True,  True,  True]])
np.full_like(arr1,fill_value=5)
array([5, 5, 5, 5, 5])
2.3.2.4 np.eye对角矩阵

对角矩阵:对角线位置是1,其他位置是0
语法:np.eye(np.eye(N, M=None, k=0, dtype=<class 'float'>, order='C', *, like=None))
(1)N,M : 行列的元素数量
(2)k : 对角线的位置,该值为正,对角线向右移动,该值为负,对角线的位置向左移动
(3)dtype : 数据类型,默认是浮点型,可以根据需求进行指定

# ?np.eye
# 行列数一致时
np.eye(7)
array([[1., 0., 0., 0., 0., 0., 0.],[0., 1., 0., 0., 0., 0., 0.],[0., 0., 1., 0., 0., 0., 0.],[0., 0., 0., 1., 0., 0., 0.],[0., 0., 0., 0., 1., 0., 0.],[0., 0., 0., 0., 0., 1., 0.],[0., 0., 0., 0., 0., 0., 1.]])
# 行列数不一致时
np.eye(3,5)
array([[1., 0., 0., 0., 0.],[0., 1., 0., 0., 0.],[0., 0., 1., 0., 0.]])
# 对角线的移动
np.eye(7,k=2)
array([[0., 0., 1., 0., 0., 0., 0.],[0., 0., 0., 1., 0., 0., 0.],[0., 0., 0., 0., 1., 0., 0.],[0., 0., 0., 0., 0., 1., 0.],[0., 0., 0., 0., 0., 0., 1.],[0., 0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0., 0.]])
np.eye(7, k=-2)
array([[0., 0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0., 0.],[1., 0., 0., 0., 0., 0., 0.],[0., 1., 0., 0., 0., 0., 0.],[0., 0., 1., 0., 0., 0., 0.],[0., 0., 0., 1., 0., 0., 0.],[0., 0., 0., 0., 1., 0., 0.]])
# 更改数据类型
np.eye(7, dtype =int)
array([[1, 0, 0, 0, 0, 0, 0],[0, 1, 0, 0, 0, 0, 0],[0, 0, 1, 0, 0, 0, 0],[0, 0, 0, 1, 0, 0, 0],[0, 0, 0, 0, 1, 0, 0],[0, 0, 0, 0, 0, 1, 0],[0, 0, 0, 0, 0, 0, 1]])

2.3.3 通过随机的方式创建数组

2.3.3.1 按照指定的分布特征构

  • 正态分布 np.random.randn,语法:np.random.randn(d0, d1, ..., dn)
  • 均匀分布 np.random.rand 范围是 [0, 1),语法:np.random.rand(d0, d1, ..., dn)
    其中d0, d1, …, dn代表每个维度上的元素数量
# 创建一个均匀分布的随机数组,利用round控制小数位数
np.random.rand(3,4).round(3)
array([[0.516, 0.725, 0.887, 0.496],[0.592, 0.773, 0.192, 0.284],[0.363, 0.058, 0.715, 0.586]])
# 如何查看它符合均匀分布,通过可视化进行观察
a4 = np.random.rand(10000)
import matplotlib.pyplot as plt
# 绘制一个直方图,观察数据分布情况
plt.hist(a4, bins=100)
plt.show()

image-20240820100038680

# 创建一个符合正态分布的数组
a5 = np.random.randn(10000)
# 绘制一个直方图,观察数据分布情况
plt.hist(a5, bins=100)
plt.show()

image-20240820100058123

2.3.3.2 按照指定的数据范围
  • np.random.randint 生成指定范围的随机整数数组
    语法:np.random.randint(low, high=None, size=None, dtype=int)

  • np.random.uniform 生成指定范围的随机浮点数数组
    语法:np.random.uniform(low=0.0, high=1.0, size=None)

    low/high :数组元素的最小/最大值
    size : 数组的形状
    返回的结果都是左闭右开的区间

import random
# 4名学生,5门功课的成绩(成绩在60~100分之间),要写101,因为右边是开区间
a6 = np.random.randint(60, 101, size=(4,5),dtype=int)
a6
array([[100,  95,  97,  99,  99],[ 67,  61,  89,  93,  63],[ 94,  67,  82,  74,  75],[ 96,  84,  76,  64,  71]])
while True:a = random.randint(60,100)print('随机值:',a)if a == 100:break
随机值: 87
随机值: 64
随机值: 65
随机值: 92
随机值: 61
随机值: 76
随机值: 96
随机值: 78
随机值: 97
随机值: 69
随机值: 60
随机值: 61
随机值: 100
# 生成5支股票7天的收盘价 8~20之间
np.random.uniform(8,20,(7,5)).round(2)
array([[10.44, 11.39, 12.04, 12.69, 11.47],[15.85, 11.96, 17.18, 12.4 , 10.39],[11.42,  8.42, 16.64, 19.38,  9.54],[10.06, 11.71,  8.19, 18.55, 11.  ],[ 8.69, 18.28, 14.5 , 11.41, 14.21],[ 9.79, 11.8 , 11.41, 10.37, 17.61],[18.11, 19.35, 17.8 , 18.09, 10.78]])
# randint生成方式
np.random.randint(80, 201, (7,5)) / 10
array([[11.3, 14.8, 12.1, 13.7,  8.3],[ 9.9, 12.2, 13. , 13.6, 10.6],[10.3, 10. , 20. , 20. ,  8.7],[ 9.2, 14.5, 11.1, 12.3, 15.4],[15.3, 15.7, 15.3,  9.5, 12.2],[14.8, 15.7, 15.2, 13.7, 14.3],[ 8.5, 13.3, 11.2,  9. , 15.2]])

2.4 高维数组(三维及以上的维度)的创建

2.3.1 用占位方法创建数组

# 创建一个三层,三行,三列的全 0 数组
a7 = np.zeros((3, 3, 3))
a7
array([[[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]],[[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]],[[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]]])
a7.ndim
3
a7.shape
(3, 3, 3)

2.3.2 使用reshape方法创建数组

2.3.2.1 在数组上调用

ndarray.reshape,语法:a.reshape(shape, order='C')
shape:希望改变成的形状,如果是int,就是一维数组,如果是int的元组,就是多维数组

# ?np.ndarray.reshape
# 创建一个5行6列,值是1~30的数组
# (1)先创建一个1~30的一维数组
a01 = np.arange(1,31)
a01
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
# (2)针对创建的数组进行reshape操作
a01_re = a01.reshape((5,6))
a01_re
array([[ 1,  2,  3,  4,  5,  6],[ 7,  8,  9, 10, 11, 12],[13, 14, 15, 16, 17, 18],[19, 20, 21, 22, 23, 24],[25, 26, 27, 28, 29, 30]])
a01_re.ndim
2
a01_re1 = a01.reshape((3,2,5))
a01_re1
array([[[ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10]],[[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]],[[21, 22, 23, 24, 25],[26, 27, 28, 29, 30]]])
a01_re1.ndim
3
2.3.2.2 在numpy上调用

np.reshape,语法:np.reshape(a, newshape, order='C'),其中a是要改变的数组
newshape:希望改变成的形状,如果是int,就是一维数组,如果是int的元组,就是多维数组

# 创建一个5行6列,值是1~30的数组
np.reshape(np.arange(1,31),(5,6))
array([[ 1,  2,  3,  4,  5,  6],[ 7,  8,  9, 10, 11, 12],[13, 14, 15, 16, 17, 18],[19, 20, 21, 22, 23, 24],[25, 26, 27, 28, 29, 30]])
np.reshape(np.arange(1,31),(5,3,2))
array([[[ 1,  2],[ 3,  4],[ 5,  6]],[[ 7,  8],[ 9, 10],[11, 12]],[[13, 14],[15, 16],[17, 18]],[[19, 20],[21, 22],[23, 24]],[[25, 26],[27, 28],[29, 30]]])
np.reshape(a01,(3,2,5))
array([[[ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10]],[[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]],[[21, 22, 23, 24, 25],[26, 27, 28, 29, 30]]])

注意:
(1)使用reshape时,要注意转换前后数组的元素数量要保持一致,否则会报错
(2)使用负数可以实现某个维度上元素数量的快速计算,不能用0,且必须被行数/列数整除,否则报错
(3)如果直接在数组上调用reshape,则newshape可以不用写成元组

# (1)使用reshape时,要注意转换前后数组的元素数量要保持一致,否则会报错
# np.reshape(a01,(4, 6))
# ValueError: cannot reshape array of size 30 into shape (4,6)
a01.shape
(30,)
# (2)使用负数可以实现某个维度上元素数量的快速计算,不能用0,且必须被行数/列数整除,否则报错
# 变成3行n列的数组
a01.reshape(3,-1)    # 会用30除以3,然后得到的数放在-1的位置上
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],[21, 22, 23, 24, 25, 26, 27, 28, 29, 30]])
a01.reshape((-1,1))
# 将数组变为多行1列的结构,类似表格中的一列(表示一个特征)
array([[ 1],[ 2],[ 3],[ 4],[ 5],[ 6],[ 7],[ 8],[ 9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30]])
a01.reshape((1,-1))    # 变成一行多列的结构(表示一个记录)
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]])
#(3)如果直接在数组上调用reshape,则newshape可以不用写成元组
a01.reshape(6,5)
array([[ 1,  2,  3,  4,  5],[ 6,  7,  8,  9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20],[21, 22, 23, 24, 25],[26, 27, 28, 29, 30]])
a01.reshape(3,-1)
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],[11, 12, 13, 14, 15, 16, 17, 18, 19, 20],[21, 22, 23, 24, 25, 26, 27, 28, 29, 30]])

三、Numpy数据类型

Python支持的数据类型不足以满足科学计算的需求,因此NumPy添加了很多其他的数据类型,它们占用的内存空间也是不同的。在NumPy中,大部分数据类型名是以数字结尾的,这个数字表示其在内存中占用的位数。

名称描述
bool_布尔型数据类型(True 或者 False)
int_默认的整数类型(类似于 C 语言中的 long,int32 或 int64)
intc与 C 的 int 类型一样,一般是 int32 或 int 64
intp用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
int8字节(-128 to 127)
int16整数(-32768 to 32767)
int32整数(-2147483648 to 2147483647)
int64整数(-9223372036854775808 to 9223372036854775807)
uint8无符号整数(0 to 255)
uint16无符号整数(0 to 65535)
uint32无符号整数(0 to 4294967295)
uint64无符号整数(0 to 18446744073709551615)
float_float64 类型的简写
float16半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
float32单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
float64双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
complex_complex128 类型的简写,即 128 位复数
complex64复数,表示双 32 位浮点数(实数部分和虚数部分)
complex128复数,表示双 64 位浮点数(实数部分和虚数部分)

非数组对象默认的数据类型是python原生数据类型,数组对象默认的数据类型是Numpy数据类型

3.1 关于溢出的问题

# 在创建对象时,尤其是非数组对象,会自动使用原生python的数据类型
a = 40
type(a)
int
b = np.arange(10)
b
# 创建的对象是数组时,会自动使用numpy的数据类型
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b.dtype
dtype('int32')
# 即使手动指定为python数据类型,也会转换为numpy数据类型
c = np.zeros((3, 3),dtype = int)
c
array([[0, 0, 0],[0, 0, 0],[0, 0, 0]])
c.dtype
dtype('int32')

可以将非数组对象的值转换为numpy数据类型

# 直接利用数据类型进行转换
a
40
a1 = np.int8(40)
a1
40
type(a1)
numpy.int8
# 溢出的问题,解决:使用更大的数据类型
d = 2 ** 20
d
1048576
d1 = np.int8(d)
d1# 输出 0
# 提醒
'''
C:\Users\LiLin\AppData\Local\Temp\ipykernel_15164\4039848811.py:1: DeprecationWarning: NumPy will stop allowing conversion of out-of-bound Python integers to integer arrays.  The conversion of 1048576 to int8 will fail in the future.
For the old behavior, usually:np.array(value).astype(dtype)
will give the desired result (the cast overflows).d1 = np.int8(d)
'''
# 使用int32进行转换
d2 = np.int32(d)
d2
1048576

3.2 python容器数据结构和numpy数组之间的转换¶

3.2.1 python容器转numpy数组

转换方法:np.array,会将容器中元素的数据类型都转换为numpy的数据类型

# 列表转数组
list1 = [1,2,3,4,5,6,7]
type(list1)
list
type(list1[1])
int
arr01 = np.array(list1)
arr01
array([1, 2, 3, 4, 5, 6, 7])
arr01.dtype
dtype('int32')

3.2.2 numpy数组转换为python原生数据类型

3.2.2.1 推导式

[int(item) for item in ndadday]

arr01
array([1, 2, 3, 4, 5, 6, 7])
arr01.dtype
dtype('int32')
list_a01 = list(arr01)
list_a01
[1, 2, 3, 4, 5, 6, 7]
# 使用list转换后,列表中的元素依然是numpy类型
type(list_a01[6])
numpy.int32

推导式:提取数组中的每个元素,转换为整数,再构成列表

list_a01x = [int(each) for each in arr01]
list_a01x
[1, 2, 3, 4, 5, 6, 7]
type(list_a01x)
list
type(list_a01x[5])
int
3.2.2.2 数组的tolist方法

ndarray.tolist():将数组转换为列表,同时将数组中每个元素的数据类型转换为对应的原生python数据类型,没有参数

list_a01y = arr01.tolist()
list_a01y
[1, 2, 3, 4, 5, 6, 7]
type(list_a01y)
list
type(list_a01y[1])
int

y will stop allowing conversion of out-of-bound Python integers to integer arrays. The conversion of 1048576 to int8 will fail in the future.
For the old behavior, usually:
np.array(value).astype(dtype)
will give the desired result (the cast overflows).
d1 = np.int8(d)
‘’’

```python
# 使用int32进行转换
d2 = np.int32(d)
d2
1048576

3.2 python容器数据结构和numpy数组之间的转换¶

3.2.1 python容器转numpy数组

转换方法:np.array,会将容器中元素的数据类型都转换为numpy的数据类型

# 列表转数组
list1 = [1,2,3,4,5,6,7]
type(list1)
list
type(list1[1])
int
arr01 = np.array(list1)
arr01
array([1, 2, 3, 4, 5, 6, 7])
arr01.dtype
dtype('int32')

3.2.2 numpy数组转换为python原生数据类型

3.2.2.1 推导式

[int(item) for item in ndadday]

arr01
array([1, 2, 3, 4, 5, 6, 7])
arr01.dtype
dtype('int32')
list_a01 = list(arr01)
list_a01
[1, 2, 3, 4, 5, 6, 7]
# 使用list转换后,列表中的元素依然是numpy类型
type(list_a01[6])
numpy.int32

推导式:提取数组中的每个元素,转换为整数,再构成列表

list_a01x = [int(each) for each in arr01]
list_a01x
[1, 2, 3, 4, 5, 6, 7]
type(list_a01x)
list
type(list_a01x[5])
int
3.2.2.2 数组的tolist方法

ndarray.tolist():将数组转换为列表,同时将数组中每个元素的数据类型转换为对应的原生python数据类型,没有参数

list_a01y = arr01.tolist()
list_a01y
[1, 2, 3, 4, 5, 6, 7]
type(list_a01y)
list
type(list_a01y[1])
int

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/405198.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux网络】select函数

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 select函数介绍select函数参数介绍select函数返回值select的工作流程TCP服务器【多路复用版】 select函数介绍 在Linux网络编程中&#xff0c;select 函数是一种非常有用的IO多路复用技术&#xff0…

基于Java和GeoTools的Shapefile矢量数据缩略图生成实践

目录 前言 一、关于GeoTools的图片生成 1、关于GtRenderer 2、关于 图像生成架构 3、流式计算绘制 二、全球空间预览生成实战 1、pom.xml中关于图像生成依赖 2、样式设置及地图资源绑定 3、图片生成绘制 4、图片生成测试 三、成果验证 1、全球范围生成 2、我国的范…

redis随笔记

缓存穿透。key不存在。恶意攻击、代码问题。加布隆过滤器&#xff0c;或者为空就返回。 缓存失效&#xff08;击穿&#xff09;。key刚好过期。缓存时间随机数。 缓存雪崩。缓存层宕机&#xff0c;一下子袭击数据库。缓存高可用、限流熔断、提前演练。 布隆过滤器就是一个key…

Python版《超级玛丽+源码》-Python制作超级玛丽游戏

小时候最喜欢玩的小游戏就是超级玛丽了&#xff0c;有刺激有又技巧&#xff0c;通关真的很难&#xff0c;救下小公主还被抓走了&#xff0c;唉&#xff0c;心累&#xff0c;最后还是硬着头皮继续闯&#xff0c;终于要通关了&#xff0c;之后再玩还是没有那么容易&#xff0c;哈…

从并发20到并发120之laravel性能优化

调优成果 遇到问题 单台服务并发20&#xff0c;平均响应时间1124ms&#xff0c;通过htop观察&#xff0c;发现cpu占用率达到100%&#xff08;包括sleep的进程&#xff09;&#xff0c;内存几乎没怎么用。 调优后 单机最大吞吐量达到120 响应时长不超过1000ms 硬件信息 …

EfficientFormer 系列算法

1. EfficientFormer V1 模型 论文地址&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/file/5452ad8ee6ea6e7dc41db1cbd31ba0b8-Paper-Conference.pdf EfficientFormer V1 基于 ViT 的模型中使用的网络架构和具体的算子&#xff0c;找到端侧低效的原因。然…

高性能web服务器nginx

目录 nginx简介 服务端 I/O 流程 Nginx 进程结构 Nginx启动流程 nginx的源码编译下载 nginx命令常见参数 nginx的配置文件详解 全局配置优化 nginx的平滑升级和回滚 nginx目录匹配优先级测试&#xff08;因为只支持访问文件&#xff0c;所有不比对匹配目录优先级&…

五、2 移位操作符赋值操作符

1、移位操作符 2、赋值操作符 “ ”赋值&#xff0c;“ ”判断是否相等 1&#xff09;连续赋值 2&#xff09;复合赋值符

C ++初阶:类和对象(上)

目录 &#x1f31e;0.前言 1. 面向过程和面向对象初步认识 2..类的引入与定义 2.1类的引入 2.2类的定义 3.类的访问限定符及其封装 3.1访问限定符 3.2封装 4.类的作用域 4.1加餐和发现 5.类的实例化 6.类对象大小的计算 6.1.内部的存储方式 6.2结构体对齐规则回顾…

一、什么是 mvvm? MVC、MVP、MVVM三种模式的区别与详解

简介 MVC、MVP、MVVM都是常见的软件架构模式。 MVC&#xff08;Model-View-Controller&#xff09;架构模式中&#xff0c;将应用程序分为三个主要部分&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&…

STM32自制手持小风扇实验

1.1 介绍&#xff1a; 实验功能说明&#xff1a;功能&#xff08;1&#xff09;按一下按键小风扇开启&#xff0c;再按一下关闭。 功能&#xff08;2&#xff09;按一下按键小风扇一档风速&#xff0c;再按一下二挡&#xff0c;依次三挡…关闭。 按键模块说明&#xff1a;按下…

什么是AR、VR、MR、XR?

时代背景 近年来随着计算机图形学、显示技术等的发展&#xff0c;视觉虚拟化技术得到了广泛的发展&#xff0c;并且越来越普及化&#xff0c;慢慢的也走入人们的视野。目前市场上视觉虚拟化技术的主流分为这几种 VR、AR、MR、XR。这几项技术并不是最近才出现的&#xff0c;VR的…

路由器VLAN配置(H3C)

路由器VLAN配置&#xff08;H3C&#xff09; 控制页面访问 路由器默认处于192.168.1.1网段&#xff08;可以短按reset重置&#xff09;&#xff0c;如果要直接使用需要设置静态IP处于同一网段&#xff1b; 对路由器进行配置也要将电脑IP手动设置为同一网段&#xff1b; 默…

执行rasa shell 遇到asyncio.exceptions.TimeoutError报错

在《树莓派3B运行rasa init和rasa shell遇到的tensorflow报错总结》一文中&#xff0c;我遇到的第7个报错是首次运行rasa shell时候碰到的。按照我在文中记录的解决方案&#xff0c;处理成功。 结果&#xff0c;今天我又一次遇到了asyncio - Task exception was never retrie…

91. 解码方法 -dp4

. - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/decode-ways/description/ 示例 1&#xff1a; 输入&#xff1a;s &…

「字符串」前缀函数|KMP匹配:规范化next数组 / LeetCode 28(C++)

概述 为什么大家总觉得KMP难&#xff1f;难的根本就不是这个算法本身。 在互联网上你可以见到八十种KMP算法的next数组定义和模式串回滚策略&#xff0c;把一切都懂得特别混乱。很多时候初学者的难点根本不在于这个算法本身&#xff0c;而是它令人痛苦的百花齐放的定义。 有…

ee trade:黄金投资与股票投资的区别

黄金和股票&#xff0c; 是金融市场中两种常见的投资工具&#xff0c; 它们拥有截然不同的特点和风险&#xff0c; 了解它们的差异&#xff0c; 可以帮助投资者制定更合理的投资策略。 一、 投资性质&#xff1a; 避险与成长&#xff0c; 两种投资方向 黄金&#xff1a; 被视…

【C++】入门篇一

【C】入门篇一 一 .缺省参数1.缺省参数的概念2. 缺省参数分类 二. 函数重载1. 函数重载概念2.函数重载代码举例 三.引用1.引用的概念2. 引用特性3. 常引用4. 使用场景(1). 做参数(2). 做返回值 5. 传值、传引用效率比较6. 引用和指针的区别7.引用和指针的不同点 一 .缺省参数 …

如何将MySQL迁移到TiDB,完成无缝业务切换?

当 MySQL 数据库的单表数据量达到了亿级&#xff0c;会发生什么&#xff1f; 这个现象表示公司的业务上了一个台阶&#xff0c;随着数据量的增加&#xff0c;公司规模也进一步扩大了&#xff0c;是非常喜人的一个改变 &#xff0c;然而随之而来的其他变化&#xff0c;就没那么…

Python | Leetcode Python题解之第354题俄罗斯套娃信封问题

题目&#xff1a; 题解&#xff1a; class Solution:def maxEnvelopes(self, envelopes: List[List[int]]) -> int:if not envelopes:return 0n len(envelopes)envelopes.sort(keylambda x: (x[0], -x[1]))f [1] * nfor i in range(n):for j in range(i):if envelopes[j]…