当前位置:   article > 正文

从Python转到Numpy (二)_转换成numpy

转换成numpy

numpy 的基本数据类型是ndarray(数组),ndarray在内存中的是一维连续存储,支持索引。换句话说,数组映射一个连续的内存块,可以使用索引值进行数据访问。索引依次由形状和数据类型定义。

  1. # 创建一个0-9的数组,改为33列的二维数组,单个元素的数据类型为np.int162个字节)
  2. z = np.arange(9).reshape(3,3).astype(np.int16)
  3. print(z.itemsize) # 单个元素的字节数
  4. 2
  5. print(z.shape) # 数组的形状
  6. (3, 3)
  7. print(Z.ndim) # 数组的维数
  8. 2
可以算出数组的stides步长,步长定义了遍历数组时每个维度中要跨步的字节数。
  1. strides = z.shape[1]*z.itemsize, z.itemsize
  2. print(strides)
  3. (6, 2)
  4. print(z.strides)
  5. # 第一个维度,也就是行方向上每行要跨出63*2)个字节
  6. # 第二个维度,也就是列方向上每列要跨出2个字节
  7. (6, 2)

数组元素布局

数组扁平化后元素布局

数组内存布局

当对数组使用索引取值时,返回的是原始数组的视图,比如

v = z[::2,::2] #两个维度上,每隔1个元素取值

数组元素布局

 

数组扁平化后元素布局

数组内存布局

区分视图和副本

首先要区分索引和花式索引,前者返回的是原始数组的视图,后者返回的是原始数据索引后的副本。修改前者的值会影响原始数组。

  1. z = np.zeros(9)
  2. z_view = z[:3]
  3. z_view[...] = 1
  4. print(z)
  5. out:[ 1. 1. 1. 0. 0. 0. 0. 0. 0.]
  6. z = np.zeros(9)
  7. z_copy = z[[0,1,2]] # 花式索引
  8. z_copy[...] = 1
  9. print(z)
  10. out:[ 0. 0. 0. 0. 0. 0. 0. 0. 0.]

如果不确定索引返回的是原始数组的视图还是副本,可以通过结果的base属性确认,如果base的值是None,则返回的结果是副本。

注意某些numpy函数返回的是视图,比如ravel,而flatten返回的是副本,虽然两者都得到扁平后的数据。

 

代码产生的临时副本

  1. X = np.ones(10, dtype=np.int)
  2. Y = np.ones(10, dtype=np.int)
  3. A = 2*X + 2*Y

运行上边的代码,除了显式的产生了X,Y和A三个数组外,还隐式的生成了两个数组2*X和2*Y。当数组非常大的时候可能会产生性能问题。解决问题的办法是显示调用numpy函数中的out参数, 明确指定输出结果到已经声明的变量。

  1. X = np.ones(10, dtype=np.int)
  2. Y = np.ones(10, dtype=np.int)
  3. np.multiply(X, 2, out=X)
  4. np.multiply(Y, 2, out=Y)
  5. np.add(X, Y, out=X)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/106425
推荐阅读
相关标签
  

闽ICP备14008679号