数据分析之Numpy库入门学习笔记

前言

在我python学到后期的时候看见了这个库Numpy。接着现在开始学习数据分析时又看见了这个名词,那么这个库很厉害吗?今天见分晓!

数据的维度

数据的维度,这里我就不想再提,直接上图吧,

(一维二维数据相关概念)[python之文件和数据格式学习笔记 | huan’s Notebook (yanghuanh1314.github.io)]

好,图上把该说的都说了,我无话可说。哈哈

在python里面数据是存放在列表中的,但是列表和数组有关系吗?在之前我就以为数组和列表是一个概念,带着这样的疑问我们继续往下看

Numpy的数组对象:ndarray

Numpy

Numpy是一个开源的python科学计算基础库,包含

  • 一个强大的N维数组对象ndarray
  • 广播功能函数
  • 整合C/C++/Fortran代码的工具
  • 线性代数、傅里叶变换、随机数生成等功能

Numpy是Scipy、Pandas等数据处理或科学计算库的基础

上面是照搬老师的ppt,就让来理解一下

ndarray是什么

看array是什么,也可以缩写为arr

image

数组的意思。

nd 呢?我的理解就说一维(1D)、二维(2D)、三维(3D)····等等nD的意思。

这也就正好解释了Numpy是处理N维数组的库。

然后我们提到了数组与列表有什么区别

很明确一点,在基础的python里面不存在数组,一开始我也很纳闷,那列表不是数组的一种吗?现在看下来。

区别

这是在Numpy官网上的发现的。我试着理解了一下。

简单的概括就说三点空间、长度与类型。如果学习过C语言,那么我想我说到这里应该已经明白了。

C语言定义一个数组要写两个参数:数组类型、数组大小。而且这个数组在这一个程序中是死的。后面不可以往里面添加元素。空间是死,除非你数组开大点,

int a[5]={1,2,3,4,5};

而python呢?首先可以看到不用定义长度,后续可以无限添加元素,其次也是我一直没试过的,原来里面的元素可以是整型、浮点型、字符,这就过分了。

>>> a = [1, 2, 3, 3.14, 0.56, 'a', 'b', 'c']
[1, 2, 3, 3.14, 0.56, 'a','b', 'c']

emmm,在C语言绝对不敢这么干。而且可以无限加元素。我也明白了为什么有人说python没有数组。

广播性

这也是Numpy的特性我想着是广播吗?这是一个机制,自动广播机制。

就是指不同形状的数组进行数值计算。

就是说有这么两组举例

import numpy as np
a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print (c)
[ 10  40  90 160]

先看着一个组,a与b的形状相同,则a[0]*b[0]a[1]*b[1]a[2]*b[2] a[3]*b[3]

a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = np.array([1,2,3])
print(a + b)
[[ 1  2  3]
 [11 12 13]
 [21 22 23]
 [31 32 33]]

那这个呢,数组形状不一样欸。但是还是出现了结果,既然没有报错,好,其实这里就用到了广播机制。

以下是广播机制的规则,<菜鸟教程>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GAuS3fuq-1649593136531)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/广播机制.6nk6l4ltosc0.webp)]

我试着理解一下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fN3mnsV6-1649593136531)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/numpy广播机制.22ft93m28ti8.webp)]

可以看出来这是两个维度不一样的数组,我对他们进行求和,结果出来了。也知道这是numpy的广播机制,但是这是怎么做到的呢

其他

因为他的底层是用C/C++编写的,所以速度比原生python速度快,都知道编译型语言执行速度快于解释型语言的。

他就就是一个科学计算库,所以一些高级的数学计算想必是小菜一碟。

它是数据分析领域最基础的一个库,之前看过一篇文章,说是搭配Pandas库绝绝子。

Numpy的引用

这个很简单了。过分了。

import numpy as np

这里用的是别名np 也可以是其他,只不过np `比较常用。

N维数组的对象:ndarray

python已有列表类型,为什么需要一个数组对象(类型)

  • 数组对象可以去掉元素间运算所需要的循环,使一维向量更像单个数据

  • 设置专门的数组对象,经过优化,可以提升这类应用的运算速度。

    且在科学计算中,一个维度所有数据的类型往往相同

  • 数组对象采用相同的数据类型,有助于节省运算和存储空间

这个怎么理解呢?

for 循环计算

a = [1,2,3,4]
b = [5,6,7,8]
c = []
for i in range(len(a)):
    c.append(a[i]*b[i])
print(c)
[5, 12, 21, 32]

numpy运算

import numpy as np
a = np.array([1,2,3,4]) 
b = np.array([5,6,7,8]) 
c = a * b 
print (c)
[ 5 12 21 32]

这样就离开了循环.

紧接着提到了效率

import numpy as np
my_arr = np.arange(1000000)
my_list = list(range(1000000))
In [10]: %time for _ in range(10): my_arr2 = my_arr * 2
Wall time: 13 ms
In [11]: %time for _ in range(10): my_list2 = [x * 2 for x in my_list] 
Wall time: 716 ms

对比一下,让两个数组里的元素都×2,numpy执行速度比for循环快的多。

这样节省空间显而易见的呀,一个整数字节是4,那么5个20

数据往往相同,什么意思,做实验,你记录的数据肯定是同一个类型把,我们在学习概率部分,记录抛硬币正面的频率,他肯定是一个小数把,不可能是一个字符、整数。

而python的列表呢?

ndarray是一个多维数组对象,由两部分构成:

  • 实际的数据
  • 描述这些数据的元数据(数据维度,数据类型等)

ndarray数组一般要求所有元素类型相同(同质),数组下标从0开始

相同元素,列表与C语言数组对比后,就应该明白什么意思了把

两部分应该是说数据的内容和你这个数组的信息把,比如里面数组元素是什么类型,有几个、维度

import numpy as np
a = np.array([[1,2,3,4],
            [5,6,7,8]])
a
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

np.array()生成一个数组,其中ndarray在程序中的别名是array

print(a)
[[1 2 3 4]
 [5 6 7 8]]

输出成[]的形式,元素由空格分开
轴(axis):保存数据的维度;秩(rank):轴的数量

什么是轴,什么是秩?

andarray对象的属性

属性说明
.ndim秩,即轴的数量或维度的数量
.shapendarray对象的尺度,对于阵列,n行m列
.sizendarray对象的个数,相当于.shape中的n*m值
.dtypendarray对象的元素类型
.itemsizendarray对象中每个元素的大小,以字节为单位

andarray对象的属性

import numpy as np
a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
a.ndim
2

2个轴

a.shape
(4, 3)

通俗的说是4行3列的数组。

第一个维度有4个方向,第二个是维度有3个元素

a.size
12

4*3=12个元素

a.dtype
dtype('int32')

里面的元素类型是int32

a.itemsize
4

一个元素占4个字节

ndarray数组的元素类型

  • 类型1:

    数据类型说明
    bool布尔类型,TureFalse
    intc与C语言中的int 类型一致,一般是int32int64
    intp用于索引的整数,与C语言中ssize_t 一致, int32int64
    int8字节长度的整型,取值:[-128, 127]
    int1616位长度的整数,取值:[-32768, 32767]
    int3232位长度的整数,取值:[-231 , 231-1]
    int6464位长度的整数,取值:[-263 , 263-1]
  • 类型2

    数据类型说明
    uint88位无符号整数,取值:[0, 255]
    uint1616位无符号整数,取值:[0, 65535]
    uint3232位无符号整数,取值:[0, 232-1]
    uint6432位无符号整数,取值:[0, 264-1]
    float1616位半精度:1位符号位,5位指数,10位尾数
    float3232位半精度:1位符号位,8位指数,23位尾数
    float64264位半精度:1位符号位,11位指数,52位尾数
  • 类型3

    数据类型说明
    complex64复数类型,实部和虚部都是32位浮点数
    complex128`复数类型,实部和虚部都是64位浮点数

什么是无符号整数?在C语言里面有这个概念,刚刚百度后发现说的就是非负数。在数学中存在一个负数,而这一类型与负数没有关系。其他的,说实话我对字节没有研究明白,还不能下过多结论。

ndarray为什么要支持这么多种类型元素?

对比:python语法仅支持整数、浮点数和复数三种类型

  • 科学计算涉及数据较多,对存储和性能都要较高的要求。
  • 对元素类型精细定义,有助于Numpy合理使用存储空间并优化性能
  • 对元素类型精细定义,有助于程序员对程序规模合理评估

如果是说一个数组出现了很多类型的数据,第一眼看上去就是乱。里面什么都有。而且浪费空间。

然后因为是对数据进行处理,那么每天就会面对不同的数据。大家想想,数据只有整数和两位小数点的小数吗?不会吧。所以就出来了。

ndarray数组的创建

从python中的列表、元组等类型创建ndarray数组

x = np.array(list/tuple)
x = np.array(list/tuple, dtype=np.float32)

np.array 不指定dtype 时,NumPy将根据数据情况关联一个dtype 类型

举例

import numpy as np
x = np.array([1,2,3,4,5])  # 列表
print(x)
[1 2 3 4 5]
import numpy as np
x = np.array((6,7,8,9,0))  # 元组
print(x)
[6 7 8 9 0]
import numpy as np
x = np.array([[1, 2, 3], (3.41), (4,5)])  # 列表和元组混合数据类型
print(x)
[list([1, 2, 3]) 3.41 (4, 5)]

但是这个会有提示,并不影响。

使用NumPy中函数创建ndarray数组

函数说明
np.arange(n)类似range() 函数,返回ndarray类型,元素从0到n-1
np.anes(shape)根据shape生成一个全1数组,shape是元组类型
np.zeros(shape)根据shape生成一个全0数组,shape是元组类型
np.full(shape, val)根据shape生成一个数组,每个元素值都是val
np.eye(n)创建一个正方形n*n单位矩阵,对角线位1,其余为0
np.ones_like(a)根据数组a的形状生成一个全1数组
np.zeros_like(a)根据数组a的形状生成一个全0数组
np.full_like(a, val)根据数组a的形状生成一个数组,每个元素值都是val

举例:

np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

很像range()

np.ones((4, 6))
array([[1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.]], dtype=float16)

4行6列,全是1

np.zeros((4, 6))
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,

np.full((3, 5), 5)
array([[5, 5, 5, 5, 5],
       [5, 5, 5, 5, 5],
       [5, 5, 5, 5, 5]])

val 值,我输的5,全是5

np.eye(5)
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

是个正方形矩阵,对角线1.

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

array([[1, 1, 1],
       [1, 1, 1]])

x是一个二维数组,根据他的形状仿一个,全是1.

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

array([[0, 0, 0],
       [0, 0, 0]])

全是0

npx = np.array([[1,2,3],[4,5,6]])  
print(x)
np.full_like(x, 5)
[[1 2 3]
 [4 5 6]]

array([[5, 5, 5],
       [5, 5, 5]])

使用NumPy中其他函数创建ndarray数组

函数说明
np.linspace()根据起止数据等间距地填充数据,形成数组
np.concatenate()将两个或多个数组合并成一个新的数组

举例

np.linspace(1,10,4)
array([ 1.,  4.,  7., 10.])

他们是等间距的7-4=4-1等差数列,1到10,4个元素,浮点数

np.linspace(1,7,4,endpoint=False)
array([1. , 2.5, 4. , 5.5])

endpoint 的参数如果是false,则不包括终止元素。我是这么想着,如果有false参数,是不是可以理解为保留两位小数

a = np.linspace(1,6,4)
b = np.linspace(1,6,4,endpoint=False)
print(a)
print(b)
[1.         2.66666667 4.33333333 6.        ]
[1.   2.25 3.5  4.75]

像不像这个意思。

a = np.linspace(1,10,4)
b = np.linspace(1,10,4,endpoint=False)
np.concatenate((a,b))
array([ 1.  ,  4.  ,  7.  , 10.  ,  1.  ,  3.25,  5.5 ,  7.75])

合并

ndarray数组的变化

对于创建后的ndarray数组,可以对其进行维度变换和元素类型变换

a = np.ones((2,3,4), dtype=np.int3)

就是说数组的维度可以转换,一维变二维,二维变一维,高维转低维,反之,低维转高维。

ndarray数组的维度变换

方法说明
.reshape(shape)不改变数组元素,返回一个shape形状的数组,原数组不变
.resize(shape).reshape() 功能一致,但修改原数组
.swapaxes(ax1, ax2)将n个维度中两个维度进行调换
.flatten()对数组进行降维,返回折叠后的一维数组,原数组不变
import numpy as np
a = np.ones((2,3,4), dtype=np.int32)
a
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]])

生成一个(2,3,4)形状的全一数组。

a.reshape((3,8))
array([[1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1]])

根据a数组的内容进行维度转换,由(2,3,4)到(3,8)

a.resize((3,8))
a
array([[1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1]])

他的功能与.reshape() 一致,但修改原数组

a.flatten()
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1])

一下子把(2,3,4)的维度转换成一维数组。

print(a)
[[[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]

 [[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]]

不改变原数组。

ndarray数组的类型变化

.astype(new_typ) 改变数组类型,但不改变数组内容。

a = np.ones((2,3,4), dtype=np.int32)
a
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]])
b = a.astype(np.float16)
b
array([[[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]],

       [[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]]], dtype=float16)

ndarray数组向列表的转换、

ls = a.totlist()

a = np.full((2,3,4),25, dtype=np.int32)
a
array([[[25, 25, 25, 25],
        [25, 25, 25, 25],
        [25, 25, 25, 25]],

       [[25, 25, 25, 25],
        [25, 25, 25, 25],
        [25, 25, 25, 25]]])
a.tolist()
[[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]],
 [[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]]]

转换成列表了。怎么看呢,前者的输出有个array提示,而后者输出没有提示

ndarray数组的操作

数组的索引与切片

  • 索引:获取数组中特定位置元素的过程
  • 切片:获取数组元素子集的过程

这个很简单,与python字符串、列表的一致,举一些例子

一维数组的切片与索引

与python的列表一致

import numpy as np
a = np.array([9,8,7,6,5])
a[2]
7

和以往类似,从0开始

a[1:4:2]
array([8, 6])

不含终止编号

多维数组的索引

规则是每一个维度一个索引值,逗号分隔

import numpy as np
a = np.arange(24).reshape(2,3,4)
a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
a[1,2,3]
23
a[0,1,2]
6
a[-1,-2,-3]
17

这个怎么说呢?从大往小缩。

高维数组的索引

多维数组的切片

  • 选取一个维度用:
  • 每个维度切片方法与一维数组相同
  • 每个维度可以使用步长跳跃切片。
import numpy as np
a = np.arange(24).reshape(2,3,4)
a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
a[:,1,-3]
array([ 5, 17])
a[:,1:3,:]
array([[[ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[16, 17, 18, 19],
        [20, 21, 22, 23]]])
a[:,:,::2]
array([[[ 0,  2],
        [ 4,  6],
        [ 8, 10]],

       [[12, 14],
        [16, 18],
        [20, 22]]])

ndarray数组的运算

数组与标量之间的运算

numpy一元函数

对ndarray中的数据执行元素级运算的函数

函数说明
np.abs(x) ,np.fabd(x)计算数组各元素的绝对值
np.sqrt(x)计算数组各元素的平方根
np.square(x)计算数组各元素的绝对值平方
np.ceil(x), np.floor(x)计算数组各元素的ceiling值或floor值
np.log(x)``np.log10(x)``np.log2(x)计算数组各元素的自然对数,10底对数,2底对数
np.rint(x)计算数组各元素的四舍五入值
np.modf(x)计算数组各元素的小数和整数部分以两个独立数组形式返回
np.cos(x),np.cosh(x),
np.sin(x),np.sinh(x),
np.tan(x),np.tanh(x),
计算数组各元素的普通型和双曲线型三角函数
np.exp(x)计算数组各元素的指数值
np.sign(x)计算数组各元素的符号值,1(+),0,-1(-)

举例

import numpy as np
x = np.array(([[[ 0,  1,  2,  3],
                [ 4,  -5,  6,  7],
                [ 8,  9, -10, 11]],
               [[-12, 13, 14, 15],
                [16, -17, 18, 19],
                [20, 21, 22, -23]]]))
x
array([[[  0,   1,   2,   3],
        [  4,  -5,   6,   7],
        [  8,   9, -10,  11]],

       [[-12,  13,  14,  15],
        [ 16, -17,  18,  19],
        [ 20,  21,  22, -23]]])

随意生成一个数组,进行操作

np.abs(x)

np.abs(x)  # 求数组的绝对值
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

可以看到有些元素是负数现在变成正数了。求绝对值。

np.sqrt(x)

np.sqrt(a)  # 求a数组各元素平方根
array([[[0.        , 1.        , 1.41421356, 1.73205081],
        [2.        , 2.23606798, 2.44948974, 2.64575131],
        [2.82842712, 3.        , 3.16227766, 3.31662479]],

       [[3.46410162, 3.60555128, 3.74165739, 3.87298335],
        [4.        , 4.12310563, 4.24264069, 4.35889894],
        [4.47213595, 4.58257569, 4.69041576, 4.79583152]]])

np.square(x)

np.square(x)  # 绝对值的平方
array([[[  0,   1,   4,   9],
        [ 16,  25,  36,  49],
        [ 64,  81, 100, 121]],

       [[144, 169, 196, 225],
        [256, 289, 324, 361],
        [400, 441, 484, 529]]], dtype=int32)

求平方

np.ceil(x), np.floor(x)

一开始我没有清楚ceiling 值和floor值是什么

  • ceiling 值:向上取整
  • floor值:向下取整

什么意思呢,举例一个小数3.14,向上取整是4。向下取值是3,这里不是四舍五入。

import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8]]
arr = np.array(data)
arr
array([[1.2 , 2.5 , 3.14, 4.23],
       [5.3 , 6.18, 7.4 , 8.  ]])

生成一个浮点数型数组

np.ceil(arr)
array([[2., 3., 4., 5.],
       [6., 7., 8., 8.]])

向上取整,1.2就是2,2.5就是3,等等。

np.floor(arr)
array([[1., 2., 3., 4.],
       [5., 6., 7., 8.]])

向下取整,1.2就是1,2.5就是2,等等。

但会发现生成的都是浮点数。

np.log(x) 系列

这是个求对数的函数。

import numpy as np
a = np.arange(1,25).reshape(2,3,4)
a
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]]])

重新生成一个数组,从1开始,0会有个提醒,不影响。

np.log(a)
array([[[0.        , 0.69314718, 1.09861229, 1.38629436],
        [1.60943791, 1.79175947, 1.94591015, 2.07944154],
        [2.19722458, 2.30258509, 2.39789527, 2.48490665]],

       [[2.56494936, 2.63905733, 2.7080502 , 2.77258872],
        [2.83321334, 2.89037176, 2.94443898, 2.99573227],
        [3.04452244, 3.09104245, 3.13549422, 3.17805383]]])
np.log10(a)
array([[[0.        , 0.30103   , 0.47712125, 0.60205999],
        [0.69897   , 0.77815125, 0.84509804, 0.90308999],
        [0.95424251, 1.        , 1.04139269, 1.07918125]],

       [[1.11394335, 1.14612804, 1.17609126, 1.20411998],
        [1.23044892, 1.25527251, 1.2787536 , 1.30103   ],
        [1.32221929, 1.34242268, 1.36172784, 1.38021124]]])
np.log2(a)
array([[[0.        , 1.        , 1.5849625 , 2.        ],
        [2.32192809, 2.5849625 , 2.80735492, 3.        ],
        [3.169925  , 3.32192809, 3.45943162, 3.5849625 ]],

       [[3.70043972, 3.80735492, 3.9068906 , 4.        ],
        [4.08746284, 4.169925  , 4.24792751, 4.32192809],
        [4.39231742, 4.45943162, 4.52356196, 4.5849625 ]]])

np.rint(x)

import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8],[11.2, 4.5, 9, 8.9]]
arr = np.array(data)
arr
array([[ 1.2 ,  2.5 ,  3.14,  4.23],
       [ 5.3 ,  6.18,  7.4 ,  8.  ],
       [11.2 ,  4.5 ,  9.  ,  8.9 ]])
np.rint(arr)
array([[ 1.,  2.,  3.,  4.],
       [ 5.,  6.,  7.,  8.],
       [11.,  4.,  9.,  9.]])

这是四舍五入,与上面的np.ceil(x), np.floor(x)不一样。虽然都是小数变整数。都是浮点数形式。

np.modf(x)

np.modf(arr)
(array([[0.2 , 0.5 , 0.14, 0.23],
        [0.3 , 0.18, 0.4 , 0.  ],
        [0.2 , 0.5 , 0.  , 0.9 ]]),
 array([[ 1.,  2.,  3.,  4.],
        [ 5.,  6.,  7.,  8.],
        [11.,  4.,  9.,  8.]]))

返回了两个数组,第一个数组存放小数部分,第二个数组是整数形式。

np.cos(x),np.cosh(x) 系列

import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8],[11.2, 4.5, 9, 8.9]]
arr = np.array(data)
arr

还用这个数组 。

np.cos(arr)
array([[ 0.36235775, -0.80114362, -0.99999873, -0.46389687],
       [ 0.55437434,  0.99468112,  0.43854733, -0.14550003],
       [ 0.20300486, -0.2107958 , -0.91113026, -0.86543521]])
np.cosh(arr)
array([[1.81065557e+00, 6.13228948e+00, 1.15735748e+01, 3.43658923e+01],
       [1.00170901e+02, 2.41497013e+02, 8.17992521e+02, 1.49047916e+03],
       [3.65652209e+04, 4.50141201e+01, 4.05154203e+03, 3.66598684e+03]])

cosX这些我不是很能理解。

np.exp(x)

import numpy as np
a = np.arange(24).reshape(2,3,4)
a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
np.exp(a)
array([[[1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01],
        [5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03],
        [2.98095799e+03, 8.10308393e+03, 2.20264658e+04, 5.98741417e+04]],

       [[1.62754791e+05, 4.42413392e+05, 1.20260428e+06, 3.26901737e+06],
        [8.88611052e+06, 2.41549528e+07, 6.56599691e+07, 1.78482301e+08],
        [4.85165195e+08, 1.31881573e+09, 3.58491285e+09, 9.74480345e+09]]])

这是个指数形式,但我也对指数不是很了解

np.sign(x)

import numpy as np
x = np.array(([[[ 0,  -1,  2,  3],
                [ 4,  -5,  -6,  7],
                [ -8,  9, -10, 11]],
               [[-12, 13, 14, 15],
                [16, -17, 18, 19],
                [20, -21, 22, -23]]]))
x
array([[[  0,  -1,   2,   3],
        [  4,  -5,  -6,   7],
        [ -8,   9, -10,  11]],

       [[-12,  13,  14,  15],
        [ 16, -17,  18,  19],
        [ 20, -21,  22, -23]]])
np.sign(x)
array([[[ 0, -1,  1,  1],
        [ 1, -1, -1,  1],
        [-1,  1, -1,  1]],

       [[-1,  1,  1,  1],
        [ 1, -1,  1,  1],
        [ 1, -1,  1, -1]]])

正数符号是1,负数符号是-1;0符号是0

numpy二元函数

函数说明
+ - * / **两个数组个元素进行对应运算
np.maximum(x,y), np.fmax(),
np.minimum(x) ,np.fmin(x)
元素级的最大值/最小值计算
np.mod(x,y)元素级的模运算
np.copysign(x,y)将数组y中各元素值的符号赋值给数组x对应元素
> < >= <= == !=算术比较,产生布尔型

上面写的有点乱,我现在重新创建两个数组。

import numpy as np
data = [[1.2, 2.5, 3.14, 4.23], [5.3, 6.18, 7.4, 8]]
x = np.arange(8).reshape(2,4)
y = np.array(data)
x
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])
y
array([[1.2 , 2.5 , 3.14, 4.23],
       [5.3 , 6.18, 7.4 , 8.  ]])

一下试验都基于x,y两个数组,且两个数组形状一致。

数组运算

x + y
array([[ 1.2 ,  3.5 ,  5.14,  7.23],
       [ 9.3 , 11.18, 13.4 , 15.  ]])
x - y
array([[-1.2 , -1.5 , -1.14, -1.23],
       [-1.3 , -1.18, -1.4 , -1.  ]])
x * y
array([[ 0.  ,  2.5 ,  6.28, 12.69],
       [21.2 , 30.9 , 44.4 , 56.  ]])
x / y
array([[0.        , 0.4       , 0.63694268, 0.70921986],
       [0.75471698, 0.80906149, 0.81081081, 0.875     ]])
x ** y
array([[0.00000000e+00, 1.00000000e+00, 8.81524093e+00, 1.04285255e+02],
       [1.55209376e+03, 2.08753914e+04, 5.73217252e+05, 5.76480100e+06]])

这就是numpy的方便之处。不用for循环即可

np.maximum(x,y), np.fmax() 系列

np.maximum(x,y)
array([[1.2 , 2.5 , 3.14, 4.23],
       [5.3 , 6.18, 7.4 , 8.  ]])
np.minimum(x,y)
array([[0., 1., 2., 3.],
       [4., 5., 6., 7.]])

这个应该是说数组各元素一一比较,x[0][0]y[0][0]比较,0-1.2 中0大。

np.mod(x,y)

np.mod(x,y)
array([[0., 1., 2., 3.],
       [4., 5., 6., 7.]])

np.copysign(x,y)

data = [[-1.2, 2.5, -3.14, 4.23], [5.3, -6.18, 7.4, -8]]
z = np.array(data)
z  # 这里需要修改一下数组,我定义成z
array([[-1.2 ,  2.5 , -3.14,  4.23],
       [ 5.3 , -6.18,  7.4 , -8.  ]])
np.copysign(x,y)
array([[-0.,  1., -2.,  3.],
       [ 4., -5.,  6., -7.]])

因为yz 的数组符号都是整数,看不出。
可以看到z数组的符号复制给了y数组。分别复制。

算术比较

x > y
array([[ True, False,  True, False],
       [False,  True, False,  True]])

x[0[0]y[0[0]比较,0>-1.2对,返回True。一下都是类似。

x < y
array([[False,  True, False,  True],
       [ True, False,  True, False]])
x >= y
array([[ True, False,  True, False],
       [False,  True, False,  True]])
x <= y
array([[False,  True, False,  True],
       [ True, False,  True, False]])
x == y
array([[False, False, False, False],
       [False, False, False, False]])
x != y
array([[ True,  True,  True,  True],
       [ True,  True,  True,  True]])

补充

有些地方当时写的时候不是很理解,等返回来看时,又不知道怎么加上去

轴与秩

我先把这句话复制过来

轴(axis):保存数据的维度;秩(rank):轴的数量

我不是很明白。

我是这么想着,轴与秩等价?假设有个二维数组,数据的维度是2,轴是2,秩是轴的数量也是2?

轴

在知乎上看到一个大牛的解释,什么是轴,一维数组(空间)只有一个轴,一个数字确定一个位置。二维呢?直角坐标系。(x,y)两个轴确定一个位置;三维呢?(x,y,z)确定一个位置。四维、五维高维他是不是也是再说需要多少个轴。

用数学里的说一维画一个轴、二维两个,三维三个,以此类推?

维度与轴等价。几个维度几个轴。但是这样理解好像还有些欠妥。

我们举例子

  • 二维数组

    轴怎么表达呢?

    二维数组轴解释

    我百度了需要numpy轴相关的定义,都是这样说的。

    二维数组有两个轴,这个都没什么可说的。但是这两个轴个有序号,看上面的轴,axis0 代表列,axis1行。但我好奇这与保存数据的维度有什么关系呢?

    然后这样方便对这两条轴上的数据进行计算。我们看看。

    这是个二维数组,axis0表示行,axis1是列、

    arr2 = np.random.randint(0,9,size=(2,3))
    arr2  # 二维
    
      array([[2, 2, 4],
             [2, 5, 3]])
    
    arr2.sum(axis=0)  # 轴0上数据求和
    
      array([4, 7, 7])
    

    2+2=4,2+5=7,4+3=7

    arr2.sum(axis=1)  # 轴1上数据求和
    
      array([ 8, 10])
    

    2+2+4=8,2+5+3=10.

    可是这与保存数据的维度有什么关系呢?

  • 三维数组

    同理。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u85bSefa-1649593136533)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/三维数组轴解释.1khe9q1tnrsw.webp)]

    arr3 = np.random.randint(0,9,size=(2,2,3))
    arr3  # 三维
    

    二维还是个平面,三维是个立体空间,不是很好理解。

    arr3.sum(axis=0)
    
    array([[13,  5, 11],
           [14,  2,  6]])
    

    这个是怎么来着呢?

    axis0

    前后两个数相加。

    arr3.sum(axis=1)
    
    array([[15,  6,  5],
           [12,  1, 12]])
    

    axsi1

    arr3.sum(axis=2)
    
    array([[16, 10],
           [13, 12]])
    

    axis2

一维数组比较特殊,我们不提,高维数组台抽象,现在不提。就看我们现在已经举例过的二维数组、三维数组来说。轴(axis)就是坐标系里的轴。二维有两个轴。三维三个、四维四个,n维n个。但是在numpy中,这个轴是由序列的,类似索引。从0开始。在我们的举例中使用来做计算的,这么说有点绕,

你指定那个轴,那么numpy就会顺着这条轴的方向进行操作。这么说会不会容易一些。好理解呢?

但我还是没想懂,这句话要说明什么。

轴(axis):保存数据的维度

秩(rank):轴的数量

如果这么说的话,有几条轴,那么秩就是几。

import numpy as np
arr1 = np.random.randint(0,9,size=(5))
arr1.ndim  # 一维
1
arr2 = np.random.randint(0,9,size=(2,3))
arr2.ndim  # 二维
2
arr3 = np.random.randint(0,9,size=(2,2,3))
arr3.ndim  # 三维
3

.ndim :秩,即轴的数量或维度的数量

那我是不是可以认为这句是返回一个数组的维度。用上面的例子来说。1是一维、2是二维、3是三维。

维度

高维数组印象

我自以为我把维度学明白了。但是随着我敲代码的时候感觉我就是停留在了一维、二维、三维的空间里,更高维我怎么想不明白。

  • 一维:一行数据
  • 二维:一个表格
  • 三维:空间
  • 高维:???

我还是分别列出把

  • 一维

    import numpy as np
    arr1 = np.random.randint(0,9,size=(5))
    arr1  # 一维
    
    array([0, 1, 8, 0, 0])
    

    很简单的一行数字。、

  • 二维数组

    arr2 = np.random.randint(0,9,size=(2,5))
    arr2  # 二维
    
    array([[3, 8, 0, 3, 7],
           [4, 8, 4, 6, 2]])
    

    可以看作由两个一维数组构成。

  • 三维数组

    arr3 = np.random.randint(0,9,size=(3,2,5))
    arr3  # 三维
    
    array([[[6, 4, 5, 0, 4],
            [7, 0, 4, 6, 0]],
    
           [[1, 1, 2, 4, 3],
            [4, 8, 0, 5, 6]],
    
           [[2, 8, 6, 8, 3],
            [6, 5, 7, 0, 1]]])
    

    可以看作是由三个二维数组构成,每个二维数组又是由两个一维数组构成。

  • 四维数组

     arr4 = np.random.randint(0,9,size=(3,2,3,5))
     arr4  # 四维
    
      array([[[[7, 5, 8, 4, 1],
               [6, 1, 1, 6, 1],
               [4, 6, 8, 2, 5]],
      
              [[8, 4, 4, 8, 6],
               [7, 1, 8, 7, 7],
               [2, 4, 2, 3, 4]]],
    
             [[[6, 7, 7, 6, 5],
               [5, 2, 6, 5, 4],
               [8, 3, 4, 5, 3]],
      
              [[2, 1, 7, 0, 3],
               [3, 5, 5, 4, 5],
               [8, 6, 1, 1 1]]],
    
             [[[6, 7, 5, 7, 0],
               [8, 5, 1, 6, 8],
               [8, 7, 8, 8, 7]],
      
              [[7, 1, 2, 3, 6],
               [4, 1, 2, 1, 0],
               [5, 8, 2, 1, 8]]]])
    

    为什么这个四维数组会这样打印呢,不管了。我们要分析一些。由三个三维数组构成,每个三维数组又是由两个二维数组构成,而这次不一样了。每个二维数组都是由三个一维数组构成

    四维数组

    他的构成成分、

  • 五维数组

    import numpy as np
    arr = np.random.randint(0,9,size=(2,2,3,2,5))
    arr 
    

    生成一个五维数组,为了节省空间,这里就不展示了。

    五维数组

    这就是五维数组的构成。随之我发现了一个规律。

  • 高维数组

    import numpy as np
    arr = np.random.randint(0,9,size=(2,2,3,2,3,2,4,5))
    arr 
    
    arr.ndim
    
    8
    

    这是一个8维数组。

    他的构成是最外层是两个七维数组、一个七维数组由两个六维数组构成、一个六维数组由三个五维数组构成、一个五维数组由两个四维数组构成、一个四维数组由三个三维数组构成,一个三维数组由两个二维数组构成,一个二维数组由四个一维数组构成,一个一维数组有5个元素。

    这个形状的组成。

    突然想到了什么,n维数组是在n-1 的数组基础上形成的,三维数组是在二维数组上形成的,二维数组是在一维数组上形成的。

    arr.shape
    
    (2, 2, 3, 2, 3, 2, 4, 5)
    

    image

    但是说了这么多我想说明什么?我也不知道,快8000字了。还是想说有一个高维数组的空间印象,我现在最高停留在三维数组。好吧,这里结束。希望以后处理不到高维数组。嘻嘻。

高维数组轴计算

想出来都难了,还考虑计算,我看了一篇文章,对数组进行降维。什么意思呢?

import numpy as np
arr = np.array([[[2, 6, 1],[3, 7, 7]],[[8, 6, 1],[2, 1, 4]]])
arr 
array([[[2, 6, 1],
        [3, 7, 7]],

       [[8, 6, 1],
        [2, 1, 4]]])

对这么一个三维数组进行降维,我先跟着教程走一遍,之后再用四维数组举例,
先把最内层的数组看成一个整体,因此如下

A = np.array([2,6,1])  # 对内部数组分别创建一个新的数组
B = np.array([3,7,7])
C = np.array([8,6,1])
D = np.array([2,1,4])
arr_new = np.array([[A, B],[C, D]])
arr_new
array([[[2, 6, 1],
        [3, 7, 7]],

       [[8, 6, 1],
        [2, 1, 4]]])

这时就是一个二维数组。
降维后
看到这张图,我直接咔咔做运算

arr_new.sum(axis=0)
array([[10, 12,  2],
       [ 5,  8, 11]])
A + C
array([10, 12,  2])
B + D
array([ 5,  8, 11])

想要说明什么,最开始的举例是数与数相加求和,而这里是数组与数组相加求和。要不你往前翻翻看看。
image
二维数组轴解释

arr_new.sum(axis=1)
array([[ 5, 13,  8],
       [10,  7,  5]])
A + B
array([ 5, 13,  8])
C + D
array([10,  7,  5])

但是三维数组有三个轴,所以axis2是什么呢?首先要说明一点,三维数组转换成二维数组,还是有第三个轴的。

arr_new.sum(axis=2)
array([[ 9, 17],
       [15,  7]])

分别对每一个一维数组求和。
xxx

举例

这个高维数组我现在也没有整明白,先不做了吧,有点费时间,我想在数据处理分析中用到最多的应该是二维数组吧,处理表格等等。

广播性

前面浅提了一下广播性,我还是没明白。

先搞明白广播机制的触发条件是两个或多个数组做运算,并且他们的形状都不相同,此刻触发机制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMxDPn5p-1649593136535)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/广播机制.6nk6l4ltosc0.webp)]

这个定义有点绕,官网也有介绍,我也不是很明白。我们先举例子。

二维数组 + 一维数组

import numpy as np
arr1 = np.random.randint(0,9,size=(2,3))
arr2 = np.random.randint(0,9,size=(3))
arr1
array([[4, 4, 5],
       [0, 8, 6]])
a1 = []
arr2
array([3, 4, 2])
arr1 + arr2
array([[ 7,  8,  7],
       [ 3, 12,  8]])

这个怎么看呢,他把一维数组无形之中转换成了二维数组,以高维看齐。
它是怎么转换着呢?复制。
广播性演示
[3,4,2] 复制一遍,一维变二维。`arr1 = [[3,4,2],[3,4,2]]
在这里我想打印一下他们的形状

arr1.shape
(2, 3)
arr2.shape
(3,)

我们在写几组例子,分析|

三维数组 + 二维数组

arr3 = np.random.randint(0,9,size=(2,2,3))
arr4 = np.random.randint(0,9,size=(2,3))
arr3
array([[[7, 8, 4],
        [6, 5, 7]],

       [[0, 8, 8],
        [1, 2, 7]]])
arr4
array([[4, 5, 6],
       [6, 3, 8]])
arr3 + arr4
array([[[11, 13, 10],
        [12,  8, 15]],

       [[ 4, 13, 14],
        [ 7,  5, 15]]])

这个二维数组发生了改变
image

紧接着打印形状

arr3.shape
(2, 2, 3)
arr4.shape
(2, 3)

三维数组 + 一维数组

arr5 = np.random.randint(0,9,size=(2,2,3))
arr6 = np.random.randint(0,9,size=(3))
arr5
array([[[5, 3, 3],
        [0, 0, 1]],

       [[3, 6, 4],
        [7, 1, 1]]])
arr6
array([7, 7, 1])
arr5 + arr6
array([[[12, 10,  4],
        [ 7,  7,  2]],

       [[10, 13,  5],
        [14,  8,  2]]])

这个一维数组被转换
image

打印形状

arr5.shape
(2, 2, 3)
arr6.shape
(3,)

不成功的例子

arr7 = np.random.randint(0,9,size=(2,2,3))
arr8 = np.random.randint(0,9,size=(4))
arr7 + arr8
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_22492/1830531957.py in <module>
----> 1 arr7 + arr8


ValueError: operands could not be broadcast together with shapes (2,2,3) (4,) 
arr9 = np.random.randint(0,9,size=(2,3))
arr10 = np.random.randint(0,9,size=(4))
arr9 + arr10
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_22492/2797848224.py in <module>
----> 1 arr9 + arr10


ValueError: operands could not be broadcast together with shapes (2,3) (4,) 
arr11 = np.random.randint(0,9,size=(2,3,5))
arr12 = np.random.randint(0,9,size=(4,5))
arr11 + arr12
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_22492/958249982.py in <module>
----> 1 arr11 + arr12


ValueError: operands could not be broadcast together with shapes (2,3,5) (4,5) 

为社么不成功呢,一开始还好好着

广播机制总结

不成功,还是和他们的形状有关系。在这里也存在的一些规则。

image

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nupyn7eu-1649593136537)(https://cdn.jsdelivr.net/gh/yanghuanh1314/MyPicture@master/image.292l5rz5n9jw.webp)]

这里提出一个名词,尾随尺寸:就是说这个形状的最后一个值,尾部值

对比这两个数组的形状,不一样,就看他们的形状的尾部值,当尾部值相等或者其中一个是1或者0时,触发机制。

image

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmId1kkH-1649593136537)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220410195402307.png)]

image

用通俗的话说,我是这么理解的np.shape返回一个数组的形状,就开始对比这两个数组的形状。从右往左作比较(最后一个数)如果相等,那就往前走,不等,需要判断是0或者是1,是的话那就与最大数相等,再往前走。否则返回一个错误

ValueError: operands could not be broadcast together

就是这样。

总结

这一章笔记,对numpy有了一个大致的了解。

数据的维度,是什么。一维数据就是一个列表,二维数据是个表格。高维数组。

numpy是什么?一个强大的科学计算库,数组对象是ndarray。怎么说呢。一开始我以为很难,因为数据分析就很难。我现在明白了就是说对数组进行计算。不学习numpy也可以,for循环,但是速度慢啊。既然说到了速度,为什么说快呢,它的底层是C/C++/Fortran等编写的。所以快。

了解了numpy是什么后,就开始对数组进行操作、创建、运算、变化等等,学习了很多的函数。现在想起来好像就记住了一两个。但是没关系,我可以以后Ctrl+F 呀。

然后就是补充的内容,轴与秩、维度、广播机制。我感觉我弄明白了一点,有感觉还是一头雾水。但是这也是刚刚学习吧,吧一些函数、概念什么的弄明白,之后在实践中慢慢理解吧。

我觉学习得维度还得是靠想像,我一开始觉得我对数据的维度学的很明白。,慢慢着我对高维有点难以理解,一维是先,二维是平面、三维是空间。那四维呢,

好了,我的学习笔记到此结束。

里面肯定有许许多多的bug,欢迎大家指出!毕竟这样成长更快。

也感谢大家可以看到这样,如果帮到了你,是我的荣幸。

谢谢大家!

~\AppData\Local\Temp/ipykernel_22492/1830531957.py in <module>
----> 1 arr7 + arr8


ValueError: operands could not be broadcast together with shapes (2,2,3) (4,) 
arr9 = np.random.randint(0,9,size=(2,3))
arr10 = np.random.randint(0,9,size=(4))
arr9 + arr10
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_22492/2797848224.py in <module>
----> 1 arr9 + arr10


ValueError: operands could not be broadcast together with shapes (2,3) (4,) 
arr11 = np.random.randint(0,9,size=(2,3,5))
arr12 = np.random.randint(0,9,size=(4,5))
arr11 + arr12
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_22492/958249982.py in <module>
----> 1 arr11 + arr12


ValueError: operands could not be broadcast together with shapes (2,3,5) (4,5) 

为社么不成功呢,一开始还好好着

广播机制总结

不成功,还是和他们的形状有关系。在这里也存在的一些规则。

[外链图片转存中…(img-ZIBc8r0Z-1649593136537)]

[外链图片转存中…(img-Nupyn7eu-1649593136537)]

这里提出一个名词,尾随尺寸:就是说这个形状的最后一个值,尾部值

对比这两个数组的形状,不一样,就看他们的形状的尾部值,当尾部值相等或者其中一个是1或者0时,触发机制。

[外链图片转存中…(img-5TaKRBTW-1649593136537)]

[外链图片转存中…(img-CmId1kkH-1649593136537)]

[外链图片转存中…(img-1Jcnkf3L-1649593136538)]

用通俗的话说,我是这么理解的np.shape返回一个数组的形状,就开始对比这两个数组的形状。从右往左作比较(最后一个数)如果相等,那就往前走,不等,需要判断是0或者是1,是的话那就与最大数相等,再往前走。否则返回一个错误

ValueError: operands could not be broadcast together

就是这样。

总结

这一章笔记,对numpy有了一个大致的了解。

数据的维度,是什么。一维数据就是一个列表,二维数据是个表格。高维数组。

numpy是什么?一个强大的科学计算库,数组对象是ndarray。怎么说呢。一开始我以为很难,因为数据分析就很难。我现在明白了就是说对数组进行计算。不学习numpy也可以,for循环,但是速度慢啊。既然说到了速度,为什么说快呢,它的底层是C/C++/Fortran等编写的。所以快。

了解了numpy是什么后,就开始对数组进行操作、创建、运算、变化等等,学习了很多的函数。现在想起来好像就记住了一两个。但是没关系,我可以以后Ctrl+F 呀。

然后就是补充的内容,轴与秩、维度、广播机制。我感觉我弄明白了一点,有感觉还是一头雾水。但是这也是刚刚学习吧,吧一些函数、概念什么的弄明白,之后在实践中慢慢理解吧。

我觉学习得维度还得是靠想像,我一开始觉得我对数据的维度学的很明白。,慢慢着我对高维有点难以理解,一维是先,二维是平面、三维是空间。那四维呢,

好了,我的学习笔记到此结束。

里面肯定有许许多多的bug,欢迎大家指出!毕竟这样成长更快。

也感谢大家可以看到这样,如果帮到了你,是我的荣幸。

谢谢大家!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值