目录
1.ndarray介绍
2.ndarray特点
1.只能存储相同数据类型的元素
2.每个维度的元素数量是固定的
3.基于C语言实现,经过大量优化的矩阵运算,实现高性能数据处理
3.属性
ndarry:N-dimensional array的缩写,属于一个Python的类
官方文档解释(翻译):
由多个具有相同类型和尺寸的元素组成的多维容器(通常具有固定尺寸)
Numpy的ndarray没有Python列表那么高的灵活性,为了保持高性能,牺牲了部分灵活性
对于一维数组,只有一个维度,所以元素数量必定是相同
对于二维数组,每行的元素数量应该是相同的,每列的元素数量应该是相同的
以此类推,每个维度元素数量是固定的不变的
· 示例:
import numpy as np
# 一维数组
first = np.array([1,2,3,4,5])
# 二维数组
second = np.array([[1,2,3,4,5],[6,7,8,9,0]])
输出· :
>>>array([1,2,3,4,5]) # 一维数组
>>>array([[1, 2, 3, 4, 5],
[6, 7, 8, 9, 0]]) # 二维数组,(2 x 3)
Python语言以简洁闻名,而C语言则比Python有着更强的运算能力,因而Numpy牺牲部分灵活性来实现高性能
T | 数组转置,适合于二维及以上的多维数组 |
data | 用于表示数组数据在Python缓冲区对象的位置 |
dtype | 元素类型 |
flags | 数据在内存中的保存方式的信息 |
flat | 将ndarray转换为一维数组的迭代器 |
imag | 虚部表示 |
real | 实部表示 |
size | 元素数量 |
itemsize | 每个元素的内存容量,以byte为单位 |
nbytes | 数组总共占据的内存大小,单位为byte |
ndim | 维度数 |
shape | 数组形式,表示为元组 |
strides | 在单个维度上,相邻元素间的距离,单位为byte, |
ctypes | 用于操作ctypes的迭代器 |
base | 数组的基类对象,类似于类的父类,表示引用的内存数据位置 |
一维数组:
>>> import numpy as np
>>> test = np.array([1,2,3,4,5,6,7,8]) # 创建一个一维数组
>>> test.T # 转置,与原来相同
array([1, 2, 3, 4, 5, 6, 7, 8])
>>> test.data # 储存位置
>>> test.flags # 保存方式
C_CONTIGUOUS : True # C:行主序
F_CONTIGUOUS : True # Fortran:列主序
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False>>> test.size # 元素数量为8
8
>>> test.dtype # 表示类型
dtype('int32')
>>> test.flat
>>> test.real
array([1, 2, 3, 4, 5, 6, 7, 8])
>>> test.imag
array([0, 0, 0, 0, 0, 0, 0, 0])
>>> test.itemsize
4>>> test.nbytes # itemsize * size
32>>> test.ndim # 维度数为一
1
>>> test.shape # 显示形状
(8,)
>>> test.ctypes
>>> test.base # 这里表示没有基类
>>> test.strides # 到相邻元素为4个字节长度
(4,)
二维数组:
>>> test_2 = test.reshape([2,4]) # 根据test创建一个二维数组
>>> test_2
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> test_2.T
array([[1, 5],
[2, 6],
[3, 7],
[4, 8]])
>>> test_2
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> test_2.data
>>> test_2.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False>>> test_2.size
8
>>> test_2.dtype
dtype('int32')
>>> test_2.shape # 形状为二维
(2, 4)
>>> test_2.ndim # 维度是2
2
>>> test_2.base # 基类是test
array([1, 2, 3, 4, 5, 6, 7, 8])>>> test_2.base is test
True
>>> test_2.strides # 第一个是行到行间距,第二个是列与列之间的间距
(16, 4)
*shape:表示数组形状。对于Numpy来说,从一维最低维度列开始,每高一个维度,将新增的维度加在shape元组的前面,即加在第一个。
一维数组表示为(a ,), 表示为列,为最低维度;
二维数组是(b, a), 在一维数组上新增了一维行,加在了列之前;
三维则是(c, b, a), 新的维度加在了行之前:
四维甚至于更高维度可以以此类推。
shape一般来说用于对照axis操作,axis=0是对最高维进行操作,后续会进行讲解~
*stride:步长,行主序和列主序一般来说每个维度步长是不相同的;而对于不同步长来说,即使数组相同运行速度也不相同
>>> x = np.ones([500000,]) # 全一数组,500000个
>>> y = np.ones([25000000,])[::50] # 大小和x相同>>> x.shape, y.shape
((50000,), (50000,))>>> x.strides,y.strides # x,y的步长不相同,相差正好是50倍
((8,), (400,))
运行比较代码
import time
import numpy as np
x = np.ones([500000, 1])
y = np.ones([25000000, 1])[::50]
c = time.time()
x.sum() # 计算总和
print(time.time() - c)
c = time.time()
y.sum() # 计算总和
print(time.time() - c) # 消耗时间
x运行时间:9.968280792236328e-4 s
y运行时间:3.9899349212646484e-3 s
可见stride较小的x运行较快,快了约30倍;但是在较小的实现中可不用考虑此差异
*行主序与列主序
行主序:指数组以一行为单位存储于内存中
a[0][0] a[0][1] a[0][2] ; a[1][0] a[1][1] a[1][2] ; a[2][0] a[2][1] a[2][2]
列主序:指数组以一列为单位存储于内存中
a[0][0] a[1][0] a[2][0] ; a[0][1] a[1][1] a[2][1] ; a[0][2] a[1][2] a[2][2]
*最详细数据请参考Numpy官方社区介绍
Numpy官方文档地址