【NumPy基础】- Numpy数组和矢量计算

简介: 【NumPy基础】- Numpy数组和矢量计算

我们为什么要学习NumPy??

说明:NumPy之于数值计算特别重要的原因之⼀,是因为它可以⾼效 处理⼤数组的数据。

1 NumPy的部分功能如下:

ndarray,⼀个具有⽮量算术运算和复杂⼴播能⼒的快速且节省空间的多维数组。

⽤于对整组数据进⾏快速运算的标准数学函数(⽆需编写循环)。

⽤于读写磁盘数据的⼯具以及⽤于操作内存映射⽂件的⼯具。

线性代数、随机数⽣成以及傅⾥叶变换功能。

⽤于集成由C、C++、Fortran等语⾔编写的代码的A C API。

2 选择NumPy的优势:
  • NumPy是在⼀个连续的内存块中存储数据,独⽴于其他Python内置对象。NumPy的C语⾔编写的算法库可以操作内存,⽽不必进⾏类型检查或其它前期⼯作。⽐起Python的内置序列,NumPy数组使⽤的内存更少。
  • NumPy可以在整个数组上执⾏复杂的计算,⽽不需要Python的for循环

1 Numpy ndarray多维数组对象

1.1 Creating ndarrays 生成
import numpy as np
#   随机生成2*3的序列
data=np.random.randn(2,3)
print(data)
print(data*10)
'''
[[ 0.06546319 -0.11897689 -1.82124962]
 [ 1.19808965 -0.30471992 -0.1017561 ]]
[[  0.65463189  -1.18976893 -18.21249625]
 [ 11.9808965   -3.04719919  -1.01756102]]
'''
# 查看数组的维度
print(data.shape)
# (2, 3)
# 查看数组的类型
print(data.dtype)
# float64
1.2 array数组
import numpy as np

data=[[1,2,3,4],[5,6,7,8]]
arr=np.array(data)
# print(arr)
# print(arr.ndim)
# print(arr.shape)
'''
[[1 2 3 4]
 [5 6 7 8]]
2
(2, 4)
'''
#   生成都是0的数组
a=np.zeros(10)  #相同ones是1
# print(a)
# [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
a=np.zeros((2,2))
# print(a)
'''
[[0. 0.]
 [0. 0.]]
'''
#   生成0~9的数组
a=np.arange(10) #左开右闭
print(a)
# [0 1 2 3 4 5 6 7 8 9]
1.3 数据类型

1)dtype查看数据的类型

a1=np.array([1,2,3],dtype=np.float64)
print(a1.dtype)
a2=np.array([1,2,3],dtype=np.int32)
print(a2.dtype)
# float64
# int32

2)astyoe数据类型的转化

a2=a2.astype(np.float64)
print(a2.dtype)
print(a2)
'''
float64
[1. 2. 3.]
'''
1.4 数组的计算
a=np.array([[1,2,3],[4,5,6],[1,2,3]])
print(a)
b=a*a
print(b)
'''
[[1 2 3]
 [4 5 6]
 [1 2 3]]
[[ 1  4  9]
 [16 25 36]
 [ 1  4  9]]
'''
print(b*0.5)
'''
[[ 0.5  2.   4.5]
 [ 8.  12.5 18. ]
 [ 0.5  2.   4.5]]
'''
1.5 基础索引与切片
a=np.arange(10)
print(a)
print(a[5])
'''
[0 1 2 3 4 5 6 7 8 9]
5
'''
print(a[5:8])
# [5 6 7]

#   将5-7复制给99
a[5:8]=99
print(a)
# [ 0  1  2  3  4 99 99 99  8  9]
a1=a[5:8]
print(a1)
# [99 99 99]
a1[1]=123
print(a1)
print(a)
'''
从输出结果可以看出复制过来的切片更改了,则原数组也会发生改变
这样Numpy在处理非常大的数组的话,不会引起内存问题
[ 99 123  99]
[  0   1   2   3   4  99 123  99   8   9]
'''

b=np.array([[1,2,3],[4,5,6]])
print(b)
print(b[1][2])
'''
[[1 2 3]
 [4 5 6]]
6
'''
1.6 布尔索引
# 这里需要注意的是,字符串型数组要与随机生成的数组保持一致
names=np.array(['Bob','Job','kangkang','Bob'])
data=np.random.randn(4,4)   #生成一个4*4的随机数
print(names)
print(data)
'''
['Bob' 'Job' 'kangkang' 'Bob']
[[-1.23685512 -0.9903232  -0.40647589 -0.09657184]
 [-0.58888265 -0.9094857   1.26346656 -0.13548616]
 [-0.78342903 -2.02202405 -0.09077977 -0.86846325]
 [ 2.2965722   0.18479656  0.0219635   1.16912506]]
'''
print(names=='Bob')
# [ True False False  True]
print(data[names=='Bob'])
'''
   按照bool的值,取为True的行
[[-1.23685512 -0.9903232  -0.40647589 -0.09657184]
 [ 2.2965722   0.18479656  0.0219635   1.16912506]]
'''
print(~(names=='Bob'))
# [False  True  True False]
print(data[~(names=='Bob')])
'''
    按照bool的值,取为原False的行,也就是取反之后的True行
[[-0.58888265 -0.9094857   1.26346656 -0.13548616]
 [-0.78342903 -2.02202405 -0.09077977 -0.86846325]]
'''
print(data[names=='Bob',1])
# [-0.9903232   0.18479656]
1.7 神奇索引
arr=np.empty((8,4))
#   empty就是创建一个8*4的内存值,也就是内存有什么创建什么值
for i in range(8):
    arr[i]=i
# print(arr)
'''
[[0. 0. 0. 0.]
 [1. 1. 1. 1.]
 [2. 2. 2. 2.]
 [3. 3. 3. 3.]
 [4. 4. 4. 4.]
 [5. 5. 5. 5.]
 [6. 6. 6. 6.]
 [7. 7. 7. 7.]]
'''

#   按照自己想要的顺序取出需要的行的数据
# print(arr[[3,5,2,0]])
'''
[[3. 3. 3. 3.]
 [5. 5. 5. 5.]
 [2. 2. 2. 2.]
 [0. 0. 0. 0.]]
'''
# print(arr[[-1,-2]])
'''
    倒着取
[[7. 7. 7. 7.]
 [6. 6. 6. 6.]]
'''
arr=np.arange(32).reshape((8,4))
# print(arr)
'''
[[ 0  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 31]]
'''
print(arr[[1,5,7,2],[0,3,1,2]])
#   最终选择的元素是:(1,0),(5,3),(7,1),(2,2),不管数组多少维,花式索引总是一维的
# [ 4 23 29 10]
1.8 数组的转置和转轴

说明:转置是重塑殴打一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)

1).T适合一、二维数组的转置

arr=np.arange(15).reshape((3,5))
# print(arr)
# print(arr.T)    #转置成5*3的数组
'''
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
[[ 0  5 10]
 [ 1  6 11]
 [ 2  7 12]
 [ 3  8 13]
 [ 4  9 14]]
'''
#   利用该操作计算矩阵的内积
a=np.dot(arr,arr.T)
print(a)
'''
[[ 30  80 130]
 [ 80 255 430]
 [130 430 730]]
'''

2).transpose适合高维数组,需要用一个由轴编号的数组才能进行转置

arr=np.arange(24).reshape((2,3,4))
# print(arr)
'''
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
'''
#   1、原来的轴:2*3*4对应的是(0,1,2)
# print(arr.transpose((0,1,2)))
'''
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
'''
# 2、现在进行轴转置:(1,0,2)对应的3*2*4
# print(arr.transpose((1,0,2)))
'''
[[[ 0  1  2  3]
  [12 13 14 15]]

 [[ 4  5  6  7]
  [16 17 18 19]]

 [[ 8  9 10 11]
  [20 21 22 23]]]
'''
# 3、现在进行轴转置:(2,1,0)对应的4*3*2
print(arr.transpose((2,1,0)))
'''
[[[ 0 12]
  [ 4 16]
  [ 8 20]]

 [[ 1 13]
  [ 5 17]
  [ 9 21]]

 [[ 2 14]
  [ 6 18]
  [10 22]]

 [[ 3 15]
  [ 7 19]
  [11 23]]]
'''

2 通用函数

说明:就是对数组的元素运算的函数

arr=np.arange(10)
# print(arr)
#   对arr里面的数组开根号
b=np.sqrt(arr)
# print(b)
'''
[0 1 2 3 4 5 6 7 8 9]
[0.         1.         1.41421356 1.73205081 2.         2.23606798
 2.44948974 2.64575131 2.82842712 3.        ]
'''
x=np.random.rand(8)
y=np.random.rand(8)

#通过本函数可以返回一个或一组服从“0~1”均匀分布的随机样本值。
# 随机样本取值范围是[0,1),不包括1。
# print(x)
'''
[0.30064764 0.73481023 0.10527066 0.50979887 0.95441699 0.13730305
 0.80034829 0.12164392]
'''
# print(y)
'''
[0.11402696 0.27831363 0.87334048 0.85939591 0.55736659 0.45990634
 0.72938544 0.65383401]
'''
#   计算x和y中元素级别最大的元素
# print(np.maximum(x,y))
'''
[0.30064764 0.73481023 0.87334048 0.85939591 0.95441699 0.45990634
 0.80034829 0.65383401]
'''
arr=np.random.rand(5)*5 #随机生成的数乘以5倍
#若随机生成的负数求根号,则返回nan
print(arr)
# [3.61367997 1.46649634 1.52355202 0.90171673 1.23587831]
remainder,whole_part=np.modf(arr)
#   保留小数部分
print(remainder)
# [0.61367997 0.46649634 0.52355202 0.90171673 0.23587831]
#保留整数部分
print(whole_part)
# [3. 1. 1. 0. 1.]
a=whole_part.astype(np.int32)
print(a)
# [1 1 3 0 3]
print(np.sign(a))
# [1 1 1 1 0]

1)一元数组操作:

2)二元数组的操作:

3 利用数组进行数据处理

points=np.arange(-5,5,0.1)
#从-5到5,精度0.1,共100个数
xs,ys=np.meshgrid(points,points) # 返回一个由xs, ys构成的坐标矩阵
# print(xs)
# print(ys)
'''
[[-5.  -4.9 -4.8 ...  4.7  4.8  4.9]
 [-5.  -4.9 -4.8 ...  4.7  4.8  4.9]
 [-5.  -4.9 -4.8 ...  4.7  4.8  4.9]
 ...
 [-5.  -4.9 -4.8 ...  4.7  4.8  4.9]
 [-5.  -4.9 -4.8 ...  4.7  4.8  4.9]
 [-5.  -4.9 -4.8 ...  4.7  4.8  4.9]]
'''
z=np.sqrt(xs**2+ys**2)
print(z)
import matplotlib.pyplot as plt
plt.imshow(z,cmap=plt.cm.gray)
plt.colorbar()
plt.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
plt.show()

3.1 数学和统计方法

1)生成数组,然后做聚类统计

arr=np.arange(6).reshape((2,3))
print(arr)
#   1、求数组的平均数
print(arr.mean())   #或  print(np.mean(arr))
# 2.5
#   2、求和
print(arr.sum())
# 15
#   3、利用axis计算该轴上的统计值
print(arr.mean(axis=0)) #axis=0表示按列求平均值,1表示按行
# [1.5 2.5 3.5]
print(arr.sum(axis=0))  #axis=0表示按列求和,1表示按行
# [3 5 7]

2)不聚合统计,由中间结果生成新的数组

arr=np.arange(8)
print(arr)
print(arr.cumsum())
'''
[0 1 2 3 4 5 6 7]
[ 0  1  3  6 10 15 21 28]
'''

3)多维数组中,累计函数(cumsum)返回的是同样大小的数组,但会根据标记轴部分聚类

arr=np.array([[0,1,2],[3,4,5],[6,7,8]])
print(arr)
print(arr.cumsum(axis=0))   #同样0表示对列操作
'''
[[0 1 2]
 [3 4 5]
 [6 7 8]]
[[ 0  1  2]
 [ 3  5  7]
 [ 9 12 15]]
'''

4)以下列举出了数组的统计方法

3.2 排序

说明:sort()方法进行就地排序

arr=np.random.randn(6)*5
# print(arr)
arr.sort()
# print(arr)
'''
[ -2.98478748  -2.67058322  -5.51832824 -12.23731593  -3.81424203
   1.33803487]
[-12.23731593  -5.51832824  -3.81424203  -2.98478748  -2.67058322
   1.33803487]
'''
#   多维数组可以在任何一个轴上排序,同理0表示列,1表示行
a=np.random.randn(3,3)
print(a)
a.sort(1)
print(a)
'''
[[ 0.69739385 -0.29640634 -0.54231462]
 [-1.60388036  0.65765065  0.11135261]
 [ 0.06904195  2.4380053   0.42962269]]
[[-0.54231462 -0.29640634  0.69739385]
 [-1.60388036  0.11135261  0.65765065]
 [ 0.06904195  0.42962269  2.4380053 ]]
'''
3.3 唯一化以及集合逻辑

说明:使用np.unique()用于找出数组中的唯一值并返回已排序的结果。也就是去除数组里面的重复值。

names=np.array(['Bob','Job','WIll','Bob'])
print(np.unique(names))
# ['Bob' 'Job' 'WIll']
arr=np.array([1,2,7,4,2,1,3,4,6])
print(np.unique(arr))
# [1 2 3 4 6 7]

4 用于数组的文件输入输出

说明:Numpy能够读写磁盘上的文本数据或二进制数据。通过np.save和np.load读写磁盘数组数据的两个主要函数。默认情况下以未压缩的原始二进制格式保存在扩展名为.npy的文件中。不过用户一般选择pandas或其他工具加载文本或者表格数据。

5 线性代数

说明:线性代数包含矩阵乘法、矩阵分解、行列式以及其他方阵。Numpy提供了一个用于矩阵乘法的dot函数

一些常用的线性代数函数

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

#   做xy 的内积
z=x.dot(y)  #等级 z=np.dot(x,y)
# print(z)
'''
[[14 20]
 [32 47]]
'''
#   一个二维数组跟一个一维数组矩阵点积之后得到一维数组
c=np.ones(3)
print(np.dot(x,c))
# [ 6. 15.]

6 伪随机数生成

以下是numpy.random中的部分函数

使用normal得到一个标准正态分布的4x4样本数组,这样的优势就是我们可以一次性生成大量样本值。

sample=np.random.normal(size=(4,4))
print(sample)
'''
[[ 2.5075111  -0.2278162   2.27533051  0.40876153]
 [-0.64022587  1.15964118 -1.59200453  1.08199528]
 [-0.56770742 -0.43835872 -0.06797861 -0.19994357]
 [ 0.9548936  -1.4356151  -1.46462771  1.29446398]]
'''

相关文章
|
4月前
|
存储 算法 数据挖掘
NumPy 数组学习手册:6~7
NumPy 数组学习手册:6~7
39 0
|
3月前
|
存储 索引 Python
一文掌握python数组numpy的全部用法(零基础学python(二))
一文掌握python数组numpy的全部用法(零基础学python(二))
34 0
|
4天前
|
存储 索引 Python
NumPy 数组切片及数据类型介绍
了解 NumPy 数组切片,用于从数组中提取子集。一维数组切片使用 `start:end:step`,如 `arr[1:5]`。二维数组切片如 `arr[1:3, 0:3]`。创建 5x5 数组并练习切片,例如打印第一行、第二列、对角线元素和 2x2 子数组。别忘了检查数据类型,如 `arr.dtype`,并使用 `astype()` 转换类型。
19 0
|
5天前
|
存储 索引 Python
NumPy 数组创建方法与索引访问详解
NumPy 的 `ndarray` 是其核心数据结构,可通过 `array()`、`zeros()`、`ones()` 和 `empty()` 函数创建。`array()` 可以将列表等转换为数组;`zeros()` 和 `ones()` 生成全零或全一数组;`empty()` 创建未定义值的数组。此外,还有 `arange()`、`linspace()`、`eye()` 和 `diag()` 等特殊函数。练习包括使用这些函数创建特定数组。
113 1
|
15天前
|
机器学习/深度学习 测试技术 数据处理
Numpy Tile:数组复制的艺术与效率之键
【4月更文挑战第21天】
21 0
|
23天前
|
存储 数据采集 数据处理
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
31 1
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
|
23天前
|
存储 算法 数据处理
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
35 0
|
23天前
|
存储 数据采集 数据挖掘
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
26 0
|
23天前
|
架构师 Java Python
NumPy 系列教程 001:入门和使用数组
NumPy 系列教程 001:入门和使用数组
20 0
|
24天前
|
存储 机器学习/深度学习 数据挖掘
自定义数据类型与NumPy结构数组详解
【4月更文挑战第17天】本文详细介绍了NumPy中的自定义数据类型和结构数组。通过`numpy.dtype`可创建自定义数据类型,如示例中的包含整数和浮点数字段的数组。结构数组能存储不同类型的元素,每行作为一个记录,包含多个字段。创建结构数组时,定义字段及其数据类型,然后通过字段名进行访问和操作。掌握这些技术能提升数据处理效率和灵活性,尤其在科学计算和数据分析领域。