2.2 NumPy数组的构造

发布时间:2023-12-08 13:00

2.2 NumPy数组的构造
ndarray定义的相同类型元素的N维数组。可以使用基于0的索引访问数组中的元素,使用起来与Python的原生数组没有什么区别。不过在实现方式上,却完全不同。
ndarray中的每一个元素都占用同样大小的内存,每一个元素都是同一种数据类型对象。除了基本的数据类型(整数、浮点数等等),数据类型也可以是某种数据结构(比如定义一个学生的基本信息数据结构为数据对象)。
实际上ndarray是用C编写实现的,然后通过接口被Python调用。有兴趣深入研究的,可以看一下numpy的源码。源码的下载地址是:
https://github.com/numpy/numpy

在NumPy的官网上有说明ndarray是如何实现的:
2.2 NumPy数组的构造_第1张图片

ndarray是一个对象,其中的data参数指向一块连续的内存区域,在此内存区域中存放的是dtype实例化对象。dtype一共支持21种内置的数据类型。在同一个ndarray的对象中,dtype是一样的,占用的内存大小也是一样的。这样的定义不如Python原始数组灵活方便,但是却可以极大的提高访问与处理速度。

需要注意的是,不是所有的ndarray对象都拥有自己的内存块,有的ndarray对象可能指向其他的ndarray内存地址。也就是说,数据可能是共享的。

使用numpy.array()实例化一个ndarray对象:

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

除了object是必要参数之外,其他的都是可选参数。

参数名称 参数说明
object 初始化ndarry的序列,可以是列表或者元组等。如果序列中有不同的类型,会自动转化为同一种类型。
dtype 指定元素的数据类型
copy 对象是否复制
order 取值为C、F或A(任意,默认)
subok 默认情况下,返回的数组被强制为基类数组。 如果为true,则返回子类
ndmin 生成数组的最小维数

1.object
最简单的就是输入一个python一维原生数组:

import numpy as np
a=np.array([1,2,10])
print(a)
输出的结果为:
[ 1  2 10]

生成多维数组,只需要输入多维原生数组就可以了:

import numpy as np
a=np.array([[1,2],[7,8]])
print(a)
输出结果:
[[1 2]
 [7 8]]

这是正常的情况。然而针对特殊的或者异常的情况,ndarray也能处理
(1)整型数和浮点数混合

import numpy as np
a=np.array([1,2.0])
print(a)
输出结果为:
[1.2.]
ndarray强制转换整型数为浮点数,以保持类型的一致。

(2)整型数、浮点数和虚数混合

import numpy as np
a=np.array([1,2.0,3+4j])
print(a)
输出结果为:
[1.+0.j 2.+0.j 3.+4.j]
所有元素强制转换为虚数,以保持类型一致。

(3)整型数、浮点数、虚数和字符串混合

import numpy as np
a=np.array([1,2.0,3+4j,'7'])
print(a)

输出结果为:
['1' '2.0' '(3+4j)' '7']
所有元素强制转换为字符串,以保持类型一致。

NumPy提供转换函数,实现强制转换的功能。在后面cast有关章节会介绍。不过一般建议使用相同类型的数据,不要混用,以免带来不可预知的错误。

(4)多维原生数组的元素不等长

import numpy as np
a=np.array([[1],[2,3]])
print(a)
输出结果为:
[list([1]) list([2, 3])]
强制转换为列表。

2.dtype
dtype定义的是ndarray的内置数据类型,不是Python的类型。在下一节会详细的介绍ndarray的数据类型。
在构造ndarray实例对象的时候,可以指定dtype类型。

import numpy as np
a=np.array([1,2,3],dtype='f')
print(a)
输出结果为:
[1.2. 3.]

尽管输入的序列元素都是整型数,但是由于指定dtype为浮点数(f代表浮点数),输出的结果为浮点数。

同样的,如果输入的序列中包含有浮点数,但是如果dtype指定为整型数的话,最后的输出结果会是整型数而不是浮点数。序列中的浮点数会只保留小数点前面的数值(就是整数部分的数值)。

3.copy
copy参数定义是否复制一份输入的数据。默认是True。Copy针对的是object参数是ndarray对象的情况。如果object是序列、数组或者元组等Python原生数据类型,copy参数是不起作用的。此时不管copy是否设置,NumPy都会拷贝一份数据。只有当object是ndarray对象的时候,copy的设置才会起作用。如果copy=False,新的ndarray对象其实只是输入的ndarray对象的一个内存地址,两个对象是共享一份数据源的。

import numpy as np
c=np.array([1,2,3])
a=np.array(c,copy=True)
b=np.array(c,copy=False)
print(a,b,c)
c[0]=100
print(a,b,c)
b[0]=20
print(a,b,c)
输出结果:
[1 2 3] [1 2 3] [1 2 3]
[1 2 3] [100   2   3] [100   2   3]
[1 2 3] [20  2  3] [20  2  3]

可以看到,数组a不受b,c变化的影响,因为数组a拷贝了一份数据,建立自己的数据源。而b和c是相互影响的,因为他们共用一份数据源。无论b或者c那个改变了数组中的值,另外一个都会受到影响。这就是copy参数的含义。

4.order
order的作用是按照C语言还是按照Fortran语言来布局内存。A表示使用默认值。C语言是行优先的,而Fortran是列优先的。

import numpy as np
arr1 = np.array([1,2,3,4,5,6,7,8],order='C')
arr2 = np.array([1,2,3,4,5,6,7,8],order='F')

print(arr1)
print(arr2)

arr1=arr1.reshape((2,4),order='C')
arr2=arr2.reshape((2,4),order='F')

print(arr1)
print(arr2)

结果为:
[1 2 3 4 5 6 7 8]
[1 2 3 4 5 6 7 8]
[[1 2 3 4]
 [5 6 7 8]]
[[1 3 5 7]
 [2 4 6 8]]

5.subok
默认是False,就是保证返回的是ndarray的基类。如果为True,返回的是子类。

import numpy as np
class C(np.ndarray):
    pass
c=C([1])
a=np.array(c,subok=False)
b=np.array(c,subok=True)
print(type(a),type(b))
print(a,b,c)
输出结果:
 
[0.0078125] [0.0078125] [0.0078125]

a返回的是ndarray而b返回的是C,这就是subok的作用。

6.ndmin
返回的最小维度。可以强制升高维度(但是不能降低维度)

import numpy as np
arr1=np.array([[1,2]],ndmin=5)
print(arr1)
输出结果为:
[[[[[1 2]]]]]

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号