首页 > 编程语言 >NumPy笔记(2)—— 使用数组进行面向数组编程

NumPy笔记(2)—— 使用数组进行面向数组编程

时间:2022-11-22 10:31:24浏览次数:40  
标签:arr True 编程 indexing np 数组 print NumPy


  • 参考:《利用python进行数据分析》第4章
  • 注意,由于本文是jupyter文档转换来的,代码不一定可以直接运行,有些注释是jupyter给出的交互结果,而非运行结果!!

文章目录

  • ​​1. 生成网格数据:np.meshgrid方法​​
  • ​​1.1 np.meshgrid​​
  • ​​1.2 使用示例​​
  • ​​2. 将条件逻辑作为数组操作:np.where方法​​
  • ​​2.1 np.where​​
  • ​​2.2 使用示例​​
  • ​​2.2.1 基础用法​​
  • ​​2.2.2 数组原位替换​​
  • ​​3. 数学和统计方法​​
  • ​​4. 布尔数组的方法​​
  • ​​4.1 统计True的个数​​
  • ​​4.2 与、或真值检查​​
  • ​​5. 排序​​
  • ​​6. 唯一值与其他集合逻辑​​
  • NumPy 数组允许用户利用简单的数组表达式完成多种数据操作任务,而无需编写大量循环。这种利用数组表达式替代显式循环语句的方法,称为 ​向量化
  • 通常,向量化的数组操作会比纯Python等价实现快一到两个数量级

1. 生成网格数据:np.meshgrid方法

1.1 np.meshgrid

  • 此方法利用坐标向量返回坐标矩阵,给定n个一维坐标数组 x1,x2,…,xn,生成 N 维坐标数组,可用于 N 维网格上 N 维标量/向量的矢量化表示
  • 原型:​​np.meshgrid(*xi, copy=True, sparse=False, indexing='xy')​
  1. ​x1,x2,...,xn​​ (array_like):表示网格坐标的一维数组
  2. ​indexing​​ ({‘xy’,‘ij’},optional):可设为 ‘xy’(输出数组使用笛卡尔索引) 或 ‘ij’(输出数组使用矩阵索引),默认值为’xy’
  3. ​sparse​​ (bool, optional):如果为True,则返回稀疏网格以节省内存,默认值为False
  4. ​copy​​​ (bool, optional):如果为False,则返回原始数组的视图以节省内存,默认值为True。 请注意​​sparse=False, copy=False​​ 可能会返回不连续的数组
  • 返回值:n个n维数组 X1, X2,…, XN
  1. 对于输入参数向量 ​​x1​​​, ​​x2​​​,…, ‘xn’,用 ​​Ni=len(xi)​​​ 表示各向量长度,则缺省 ​​indexing='xy'​​​ 时返回数组形状为 ​​.shape = (N1, N2, N3 ,...Nn)​​​;​​indexing='ij'​​​ 时返回数组形状为 ​​(N2, N1, N3,...Nn)​​。
  2. 缺省 ​​indexing='xy'​​​ 时,X1的第0轴(行)使用x1重复填充,X2的第1轴(列)使用x2重复填充;​​indexing='ij'​​ 时X1的第1轴(列)使用x1重复填充,X2的第0轴(行)使用x2重复填充。X1和X2在两种设定下的返回值都是互为转置关系。
  3. 对于更高的维度,可以看作把二维状态下的每个元素扩展为一维向量,​​indexing​​ 参数不再有作用
  • 说明:​indexing参数可以有点抽象,这个参数仅仅对前两个维度有效,举个二维的例子,假设输入两个一维数组x和y,则
  1. indexing='xy' 时,可以像笛卡尔坐标系一样把xy理解为x轴和y轴,返回二维数组的尺寸就是 ​​.shape = (y.size,x.size)​
  2. indexing='ij' 时,则像矩阵一样把xy理解为行数和列数,返回二维数组的尺寸就是 ​​.shape = (x.size,y.size)​
  • 测试
import numpy as np

x = np.arange(5)
y = np.arange(3)

x1,y1 = np.meshgrid(x,y,indexing='ij')
x2,y2 = np.meshgrid(x,y)
print('indexing = ij')
print(x1)
print(y1,'\n')
print('indexing = xy')
print(x2)
print(y2,'\n')

print('转置关系')
print(x1[4,2],y1[4,2])
print(x2[2,4],y2[2,4])

'''
indexing = ij
[[0 0 0]
[1 1 1]
[2 2 2]
[3 3 3]
[4 4 4]]
[[0 1 2]
[0 1 2]
[0 1 2]
[0 1 2]
[0 1 2]]

indexing = xy
[[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]]
[[0 0 0 0 0]
[1 1 1 1 1]
[2 2 2 2 2]]

转置关系
4 2
4 2
'''

1.2 使用示例

  • 现在要对一些网格数据计算函数 NumPy笔记(2)—— 使用数组进行面向数组编程_numpy
import matplotlib.pyplot as plt

# 生成网格数据
points = np.arange(-5,5,0.01)
xs,ys = np.meshgrid(points,points)

# 计算函数
z = np.sqrt(xs**2 + ys**2)

# 可视化
plt.imshow(z,cmap=plt.cm.gray)
plt.colorbar()

NumPy笔记(2)—— 使用数组进行面向数组编程_数组_02

2. 将条件逻辑作为数组操作:np.where方法

2.1 np.where

  • 此函数是三元表达式 x if condition else y 的向量化版本
  • 原型:​​where(condition, [x, y])​
  1. ​condition​​​ (array_like,bool):如果为真,则选则 ​​x​​​,否则选则 ​​y​
  2. ​x,y​​​ (array_like):可供选择的值,可以是数组,也可以是标量。​​x​​​、​​y​​​ 和 ​​condition​​ 需要可以广播到某种形状
  • 注意:当仅提供 ​​condition​​​ 时,此函数是 ​​np.asarray(condition).nonzero()​​ 的简写

2.2 使用示例

2.2.1 基础用法

  • 假设我们有两个数值数组 ​​xarr​​ 和 ​​yarr​​,我们希望依据一个布尔数组​​cond​​ 选择元素。当 ​​cond​​ 中元素为 ​​True​​ 时,取 ​​xarr​​ 中的对应元素值,否则取 ​​yarr​​ 中的对应元素值。通常我们使用列表推导式完成这种操作
xarr = np.array([1,2,3,4,5])
yarr = np.array([6,7,8,9,0])
cond = np.array([True,False,True,True,False])
result = [(x if c else y) for x,y,c in zip(xarr,yarr,cond)]
print(result)

# [1, 7, 3, 4, 0]
  • 这样做的问题在于,
  1. 数组很大时,速度缓慢
  2. 仅适用于一维情况

这时就适于使用​​np.where​​ 方法

result = np.where(cond,xarr,yarr)
print(result) # [1 7 3 4 0]

2.2.2 数组原位替换

  • ​np.where​​​ 的后两个参数 ​​[x, y]​​ 不一定是数组,也可以是标量。where的一个经典用法,就是根据一定的条件,对数组中元素进行原位替换
print('随机数组')
arr = np.random.randn(4,4)
print(arr,'\n')

print('标量原位替换')
print(np.where(arr>0,2,-2),'\n')

print('数组原位替换')
print(np.where(arr>0,2,arr))

'''
随机数组
[[ 0.6818313 1.10788644 0.60707372 -0.7961009 ]
[-0.69947074 1.57684828 1.97240362 0.6681626 ]
[-0.78550736 -0.65122289 0.44938015 -1.86345715]
[ 0.18658391 -1.19279691 0.20794079 -0.86630991]]

标量原位替换
[[ 2 2 2 -2]
[-2 2 2 2]
[-2 -2 2 -2]
[ 2 -2 2 -2]]

数组原位替换
[[ 2. 2. 2. -0.7961009 ]
[-0.69947074 2. 2. 2. ]
[-0.78550736 -0.65122289 2. -1.86345715]
[ 2. -1.19279691 2. -0.86630991]]
'''

3. 数学和统计方法

  • NumPy提供了许多关于计算整个数组统计值或关于轴向数据的数学函数,可以作为数组类型的方法被调用。

方法

描述

sum

沿轴向计算所有元素的累加和,0长度的数组,累加和为0

mean

数学平均,0长度的数组平均值为NaN

std, var

标准差和方差,可以选择自由度调整(默认分母为n)

min, max

最小值 & 最大值

argmin, argmax

最小值索引 & 最大值索引

cumsum

从0开始元素累积和

cumprod

从1开始元素累积积

  • 在调用时有两种等价方法
  1. 直接调用数组示例的方法,如 ​​arr.sum()​
  2. 使用顶层的NumPy函数,如 ​​np.sum(arr)​
  • 部分测试
print('生成一些随机数据')
arr = np.random.randn(5,4)
print(arr,'\n')

print('数组均值')
print(np.mean(arr),'\n')

print('数组累加和')
print(arr.sum(),'\n')

print('第0轴(行)轴向均值')
print(arr.mean(axis = 0),'\n')

print('第1轴(列)轴向累加和')
print(arr.sum(axis = 1),'\n')

'''
生成一些随机数据
[[-1.14758004 -0.672113 -0.13183887 -2.47382142]
[-0.41932578 -1.3022716 1.79016834 0.61126159]
[-0.76037654 0.81149644 -2.15071079 -0.97268024]
[ 2.12643459 0.44006178 0.57575081 -1.47044089]
[ 1.11763418 0.72242666 -0.4468634 -1.48691387]]

数组均值
-0.26198510217397003

数组累加和
-5.239702043479401

第0轴(行)轴向均值
[ 1.83357284e-01 -7.99443369e-05 -7.26987828e-02 -1.15851897e+00]

第1轴(列)轴向累加和
[-4.42535333 0.67983255 -3.07227113 1.67180629 -0.09371643]
'''
arr = np.array([1,2,3,4,5,6,7])
print('原始数据')
print(arr,'\n')

print('cumsum返回累加中间结果')
print(arr.cumsum(),'\n')

print('cumprod返回累积极中间结果')
print(arr.cumprod(),'\n')

arr = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
print('原始数据')
print(arr,'\n')

print('第0轴(行)轴向累加')
print(arr.cumsum(axis=0),'\n')

print('第1轴(列)轴向累积')
print(arr.cumprod(axis=1))

'''
原始数据
[1 2 3 4 5 6 7]

cumsum返回累加中间结果
[ 1 3 6 10 15 21 28]

cumprod返回累积极中间结果
[ 1 2 6 24 120 720 5040]

原始数据
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]

第0轴(行)轴向累加
[[ 0 1 2]
[ 3 5 7]
[ 9 12 15]
[18 22 26]]

第1轴(列)轴向累积
[[ 0 0 0]
[ 3 12 60]
[ 6 42 336]
[ 9 90 990]]
'''

4. 布尔数组的方法

4.1 统计True的个数

  • NumPy中布尔值通常会被视作1 (True) 和0 (False),因此可以用​​sum​​方法计算布尔数组中 ​​True​​ 的个数
arr = np.random.randn(100)
print((arr>0).sum()) # 51

4.2 与、或真值检查

  • 布尔数组的典型用法是判断其所有元素的与、或结果,这需要用到两个方法
  1. ​any​​​:检查数组中是否至少有一个 ​​True​​,即或结果
  2. ​all​​​:检查数组中是否全部都是 ​​True​​,即与结果

这两个方法也可用于非布尔值数组,所有非零元素按True处理

bools = np.array([False,False,True,False])

print(bools.any()) # True
print(bools.all()) # False

5. 排序

  • 类似Python中的列表类型,NumPy数组可以使用​​sort​​方法按位置排序
  • 原型 ​​arr.sort(axis=-1, kind=None, order=None)​
  1. ​axis​​ (int, optional):要排序的轴,默认值-1,表示沿最后一个轴排序,设置​​None​​代表所有元素拉平后排序
  2. ​kind​​ ({‘quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’},optional):可选的排序算法,默认为 “quicksort”。注意,“stable” 和 “mergesort” 都在底层使用 timsort,通常,实际实现会因数据类型而异。 保留 “mergesort” 选项是为了向后兼容
  3. ​order​​ (str 或 str list,optional):多级排序的顺序,需要构建一个field
  • 说明:
  1. 可以在多维数组中,传入axis参数以指定排序的维度
  2. 可以使用两种方式调用排序方法,​arr.sort 在原位进行排序;​np.sort(arr)​ 返回一个排序好的数组的拷贝
  3. NumPy中的sort函数仅支持排升序,要排降序,可以用这种技巧 ​​arr = np.sort(arr)[::-1]​
  • 示例
arr = np.random.randn(6)
print('原数组')
print(arr)
print('排升序')
print(np.sort(arr))
print('排降序')
print(np.sort(arr)[::-1],'\n')

arr = np.arange(14,0,-1)
arr.resize(5,3)
print('原数组')
print(arr)
print('第0轴(行)轴向排序')
print(np.sort(arr,axis=0))
print('第1轴(列)轴向排序')
print(np.sort(arr,axis=1))

'''
原数组
[-0.42145353 -0.68593585 0.0829771 -0.23195342 -0.12941807 -1.91235085]
排升序
[-1.91235085 -0.68593585 -0.42145353 -0.23195342 -0.12941807 0.0829771 ]
排降序
[ 0.0829771 -0.12941807 -0.23195342 -0.42145353 -0.68593585 -1.91235085]

原数组
[[14 13 12]
[11 10 9]
[ 8 7 6]
[ 5 4 3]
[ 2 1 0]]
第0轴(行)轴向排序
[[ 2 1 0]
[ 5 4 3]
[ 8 7 6]
[11 10 9]
[14 13 12]]
第1轴(列)轴向排序
[[12 13 14]
[ 9 10 11]
[ 6 7 8]
[ 3 4 5]
[ 0 1 2]]
'''

6. 唯一值与其他集合逻辑

  • NumPy包含一些针对一维ndarray的基础集合操作

方法

描述

unique(x)

计算x的唯一值

intersect1d(x,y)

计算x和y的交集,并排序

union1d(x,y)

计算x和y的并集,并排序

in1d(x,y)

计算x中的元素是否包含在y中,返回一个布尔数组

setdiff1d(x,y)

差集,在x中但不在y中的元素

setxor1d(x,y)

异或集,在x或y中,但不属于x , y交集的元素

  • 部分测试
names = np.array(['Tom','Bob','Bill','Tom','Bob'])
print(np.unique(names)) # ['Bill' 'Bob' 'Tom']

ints = np.array([1,1,2,2,3,3,3,4,5,6,6,6,6])
print(np.unique(ints)) # [1 2 3 4 5 6]

values = np.array([6,0,0,3,2,5,6])
print(np.in1d(values,[2,3,6])) # [ True False False True True False True]

v1 = np.array([4,3,2,1])
v2 = np.array([8,7,6,3,1])
print(np.intersect1d(v1,v2)) # [1 3]


标签:arr,True,编程,indexing,np,数组,print,NumPy
From: https://blog.51cto.com/u_15887260/5876724

相关文章

  • 极客编程python入门-切片
    切片取一个list或tuple的部分元素是非常常见的操作。>>>L=['Michael','Sarah','Tracy','Bob','Jack']>>>[L[0],L[1],L[2]]['Michael','Sarah','Tracy']Python提......
  • 数组,对象解构
    数组解构varnames=["abc","cba",undefined,"nba","mba"]基本使用var[name1,name2,name3]=names顺序问题:严格的顺序var[name1,,nam......
  • 数据分析三剑客-numpy模块
    什么是数据分析是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律使得数据的价值最大化分析用户的消费行为制定促销活动的方案......
  • C#中byte[]字节数组复制的常用方法
    简单总结了5种字节数组的复制方法for循环实现复制较为原始的遍历写法,不太推荐byte[]data=newbyte[]{0,1,2,3,4,5,6,7,8,9};byte[]data1=newbyte[data.length]......
  • 22.大促期间网络编程与安全解读【双元】(1) _完全没用
               ......
  • Java NIO编程实例
     文章目录前言一、NIO与BIO的比较二、Buffer的机制及其子类1.Buffer的使用2.Buffer的四个基本类型三、Channel的使用1.Channel的特征2.Channel的子......
  • 数组部分基础&冒泡排序
    数组基础知识 1.数组的创建格式:变量(数组)类型变量(数组)名=变量(数组)值int[]nums;//声明一个数组nums=newint[10];//创建一个数组int[]nums=new......
  • 自己学网页编程。
    自学网页编程的CSS代码展示:*{  margin:0;  padding:0;}.w{  width:1200px;  margin:auto;}body{  background-color:#f3f5f7; ......
  • 代码随想录day6---LeetCode 242.有效的字母异位词 & 349. 两个数组的交集&202. 快乐数
    LeetCode242.有效的字母异位词给定两个字符串s和t,编写一个函数来判断t是否是s的字母异位词。注意:若s和t中每个字符出现的次数都相同,则称s和t互为字母......
  • LC[53] 最大子数组和
    原题链接:https://leetcode.cn/problems/maximum-subarray/description/WA了一次,是因为没有考虑到负数的情况AC代码:classSolution{public:intmaxSubArray(vecto......