来源:《利用Python进行数据分析·第2版》
numpy -- Numerical Python 数值的python
numpy弥补了作为通用编程语言的python在数值计算方面能力弱,速度慢的能力不足
numpy VS Python测试代码
import datetime as dt
import numpy as np # np是约定俗成的
n = 100000
start = dt.datetime.now()
A, B = [], []
for i in range(n):
A.append(i ** 2)
B.append(i ** 3)
C = []
for a, b in zip(A, B):
C.append(a + b)
print((dt.datetime.now() - start).microseconds)
start = dt.datetime.now()
A, B = np.arange(n) ** 2, np.arange(n) ** 3
C = A + B
print((dt.datetime.now() - start).microseconds)
C:\Users\lubaba\PycharmProjects\lu\venv\Scripts\python.exe C:/data/data-science/day01/code/vector.py
519341
NumPy最重要的一个特点就是其N维数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器。你可以利用这种数组对整块数据执行一些数学运算,其语法跟标量元素之间的运算一样。
要明白Python是如何利用与标量值类似的语法进行批次计算,我先引入NumPy,然后生成一个包含随机数据的小数组:
In [2]: data = np.random.randn(2, 3)
In [3]: data
Out[3]:
array([[ 0.14878139, 0.08292136, -0.18053245],
[ 0.57409287, 1.02747153, -1.0838187 ]])
In [6]: data * 10
Out[6]:
array([[ 1.48781389, 0.8292136 , -1.80532446],
[ 5.74092872, 10.27471525, -10.83818695]])
In [7]: data + data
Out[7]:
array([[ 0.29756278, 0.16584272, -0.36106489],
[ 1.14818574, 2.05494305, -2.16763739]])
ndarray是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的。每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数组数据类型的对象):
In [10]: data.shape
Out[10]: (2, 3)
In [11]: data.dtype
Out[11]: dtype('float64')
创建数组最简单的办法就是使用array函数。它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的NumPy数组。以一个列表的转换为例:
In [12]: data1 = [1, 2, 3.0, 4]
In [19]: array1 = np.array(data1)
In [20]: array1
Out[20]: array([1., 2., 3., 4.])
嵌套序列(比如由一组等长列表组成的列表)将会被转换为一个多维数组:
In [21]: data = [[1 ,2 ,3, 4], [5, 6, 7, 8]]
In [23]: array3 = np.array(data)
In [25]: array3
Out[25]:
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
可以用属性ndim和shape验证数组维度:
In [26]: array3.ndim
Out[26]: 2
In [27]: array3.shape
Out[27]: (2, 4)
除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组即可:
In [34]: np.zeros(5)
Out[34]: array([0., 0., 0., 0., 0.])
In [35]: np.zeros((3, 5))
Out[35]:
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
In [36]: np.empty((2, 3, 2))
Out[36]:
array([[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
arange是Python内置函数range的数组版:
In [37]: np.arange(15)
Out[37]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
列出了一些数组创建函数。由于NumPy关注的是数值计算,因此,如果没有特别指定,数据类型基本都是float64(浮点数)。
dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息:
In [39]: array1 = np.array([1, 2, 3], dtype=np.float64)
In [40]: array2 = np.array([1, 2, 3], dtype=np.int32)
In [41]: array1.dtype
Out[41]: dtype('float64')
In [43]: array2.dtype
Out[43]: dtype('int32')
dtype是NumPy灵活交互其它系统的源泉之一。多数情况下,它们直接映射到相应的机器表示,这使得“读写磁盘上的二进制数据流”以及“集成低级语言代码(如C、Fortran)”等工作变得更加简单。数值型dtype的命名方式相同:一个类型名(如float或int),后面跟一个用于表示各元素位长的数字。标准的双精度浮点值(即Python中的float对象)需要占用8字节(即64位)。因此,该类型在NumPy中就记作float64。表4-2列出了NumPy所支持的全部数据类型。
你可以通过ndarray的astype方法明确地将一个数组从一个dtype转换成另一个dtype:
In [44]: arr = np.array([1, 2, 3, 4])
In [45]: arr.dtype
Out[45]: dtype('int32')
In [46]: float_arr = arr.astype(np.float64)
In [49]: float_arr.dtype
Out[49]: dtype('float64')
在本例中,整数被转换成了浮点数。如果将浮点数转换成整数,则小数部分将会被截取删除:
In [50]: arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
In [51]: arr
Out[51]: array([ 3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
In [52]: arr.astype(np.int32)
Out[52]: array([ 3, -1, -2, 0, 12, 10])
In [54]: arr.astype(np.int32).dtype
Out[54]: dtype('int32')
如果某字符串数组表示的全是数字,也可以用astype将其转换为数值形式:
In [55]: num_str = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
In [56]: num_str.astype(np.float64)
Out[56]: array([ 1.25, -9.6 , 42. ])
使用numpy.string_类型时,一定要小心,因为NumPy的字符串数据是大小固定的,发生截取时,不会发出警告。pandas提供了更多非数值数据的便利的处理方法。
你还可以用简洁的类型代码来表示dtype:
In [49]: empty_uint32 = np.empty(8, dtype='u4')
In [50]: empty_uint32