CHAPTER4 Numpy基础:数组与向量化计算(Arrays and Vectories)

1、背景介绍(introduction)

在数值计算领域,说Numpy是python最重要的包也不为过。在numpy中有下面这些东西: nadarry,一种高效多维数组,提供了基于数组的便捷算术操作及灵活的广播功能。(broadcasting) 便利的数组函数 用于读取/写入(reading/writing)数据到磁盘的便利工具 线性代数,随机生成,傅里叶变换能力 可以用CAPI来写C,C++,或FORTRAN 通过学习理解numpy中数组和数组的导向计算,能帮我们理解pandas之类的工具。

2、方法及数据(methonds and data)

2.1The Numpy ndarray: A Multidimensional Array Object(nadarry:多维数组对象)

N-dimensisonal array object(n维数组对象),or ndarray,这是numpy的关键特征。先来尝试一下,生成一个随机数组:

In [6]:
import numpy as np
In [4]:
# Generate some random data生成随机数组
data = np.random.randn(2,3)

设置种子(随便设置一个有趣的数字),确保每次生成的随机数是一致的。如果不设置那嚒每次随机的数组 不一样

In [5]:
np.random.seed(123)
In [6]:
data
Out[6]:
array([[ 0.46135328,  0.32250428, -0.19077805],
       [ 1.06864943,  0.05923916, -0.10650734]])
In [7]:
data.ndim
Out[7]:
2

一个ndarray是一个通用的多维数组的同类数据容器,也就是说它包含的每一个元素均为相同类型。每个数组都有一个shape,来表示维数的大小,而用dtype表示数据的类型

In [8]:
data.shape
Out[8]:
(2, 3)
In [9]:
data.dtype
Out[9]:
dtype('float64')

进行一些数学运算

In [10]:
data*10
Out[10]:
array([[ 4.61353275,  3.22504279, -1.90778049],
       [10.6864943 ,  0.59239157, -1.06507342]])
In [11]:
data+data
Out[11]:
array([[ 0.92270655,  0.64500856, -0.3815561 ],
       [ 2.13729886,  0.11847831, -0.21301468]])
In [12]:
al=np.array([[1,2],[3,4],[5,6]])
al
Out[12]:
array([[1, 2],
       [3, 4],
       [5, 6]])
In [13]:
al*al
Out[13]:
array([[ 1,  4],
       [ 9, 16],
       [25, 36]])

实现数组的转置,T

In [14]:
al.T
Out[14]:
array([[1, 3, 5],
       [2, 4, 6]])

把一个数组的维数转换成另一个数组,实现重构reshape()

In [22]:
al.reshape(2,3)
Out[22]:
array([[1, 2, 3],
       [4, 5, 6]])

实现数组的点乘dot 下面维al数组与其转置数组的乘积,最终为3*3

In [25]:
al.dot(al.T)
Out[25]:
array([[ 5, 11, 17],
       [11, 25, 39],
       [17, 39, 61]])

2.1.1创建n维数组,生成ndarray

In [13]:
datal=[6,7.5,80,1]
arr1=np.array(datal)
arr1
Out[13]:
array([ 6. ,  7.5, 80. ,  1. ])

嵌套序列能被转换为多维数组:

In [12]:
data2=[[1,2,3,4],[5,6,7,8]]
arr2=np.array(data2)
arr2
Out[12]:
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

因为data2是一个包含列表的列表(list of lists), 所以arr2维数为2,我们能用ndim和shape属性夹来确认

In [5]:
print(arr2.ndim)
print(arr2.shape)
2
(2, 4)

除非主动声明,否则np.array会自动推断生成的数据类型,并存储在一个特殊的元数据dtype中

In [14]:
arr1.dtype
Out[14]:
dtype('float64')
In [22]:
arr2.dtype
Out[22]:
dtype('int32')

除了np.array,还有一些其他函数能创建数组,比如给定长度及形状后,zeros可以一次性创造全0数组,ones可以一次性创造全1数组。empty可以创建一个没有初始化数值的数组

In [27]:
np.zeros(10) #生成全为0的一维数组,参数为shape
Out[27]:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [36]:
np.zeros((3,6)) #生成全为0的二维数组
Out[36]:
array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])
In [35]:
np.empty((2,3,2)) #empty并不能保证返回的所有是0的数组,某些情况下,会返回为初始化的垃圾数值,比如上面
Out[35]:
array([[[1.19014900e-311, 3.16202013e-322],
        [0.00000000e+000, 0.00000000e+000],
        [0.00000000e+000, 1.34033316e-075]],

       [[2.16612719e+184, 1.79253058e+160],
        [7.62780957e+169, 1.09395731e-042],
        [1.21544411e-046, 2.46364746e+184]]])

arrange是一个数组版的Python range函数:

In [43]:
np.arange(3,8,2) #括号参数(i,j,k),i为起始值,j为终值,k为步长
Out[43]:
array([3, 5, 7])
In [6]:
np.arange(15).reshape(3,5) #'int' object is not callable
Out[6]:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

2.1.2 Data Types for ndarrays(ndarray的数据类型)

dtype保存数据的类型:

In [30]:
arr3=np.array([1,2,3],dtype=np.float64)
In [31]:
arr3
Out[31]:
array([1., 2., 3.])
In [32]:
arr4=np.array([1,2,3],dtype=np.int32)
In [33]:
arr4.dtype
Out[33]:
dtype('int32')

可以使用astype方法显式地转换数组的数据类型

In [15]:
arr=np.array([1,2,3,4,5])
In [16]:
arr.dtype
Out[16]:
dtype('int32')
In [17]:
float_arr=arr.astype(np.float64)
In [18]:
float_arr.dtype
Out[18]:
dtype('float64')
In [19]:
arr=np.array([3.7,-1.2,-2.6,0.5,12.9,10.1])
In [20]:
arr
Out[20]:
array([ 3.7, -1.2, -2.6,  0.5, 12.9, 10.1])
In [21]:
arr.astype(np.int32)
Out[21]:
array([ 3, -1, -2,  0, 12, 10])

如果你有一个数组,里面的元素都是表达数字含义的字符串,也可以通过astype将字符串转换为数字
In [24]:
numeric_strings=np.array(['1.25','-9.6','42'],dtype=np.string_)
In [25]:
numeric_strings.astype(float)
Out[25]:
array([ 1.25, -9.6 , 42.  ])

如果因为某些原因导致转换类型失败(比如字符串无法砖混为float64位时),将会抛出一个valueerror。这里我们可以使用float来代替np.float64,时因为NumPy可以使用相同别名来表征与Python精度相同的Python数据类型

In [26]:
in_array=np.arange(10)
In [27]:
calibers=np.array([.22,.270,.357,.380,.44,.50],dtype=np.float64)
In [28]:
in_array.astype(calibers.dtype)
Out[28]:
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])

也可以用类型代码来传入数据类型

In [29]:
empty_uint32=np.empty(8,dtype='u4')
In [30]:
empty_uint32
Out[30]:
array([0, 0, 0, 0, 0, 0, 0, 0], dtype=uint32)

2.1.3 NumPy数组算数

In [31]:
arr=np.array([[1.,2.,3.],[4.,5.,6.]])
In [32]:
arr
Out[32]:
array([[1., 2., 3.],
       [4., 5., 6.]])
In [33]:
arr*arr
Out[33]:
array([[ 1.,  4.,  9.],
       [16., 25., 36.]])
In [34]:
1/arr
Out[34]:
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])
In [35]:
arr**0.5
Out[35]:
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

同尺寸数组之间比较,会产生一个布尔值数组
In [36]:
arr2=np.array([[0.,4.,1.],[7.,2.,12.]])
In [37]:
arr2
Out[37]:
array([[ 0.,  4.,  1.],
       [ 7.,  2., 12.]])
In [39]:
arr2>arr
Out[39]:
array([[False,  True, False],
       [ True, False,  True]])

2.1.4 Basic Indexing and Slicing(基本的索引和切片)

有多种方式可以让我们选中数据的子集或者某个单个元素

In [7]:
arr=np.arange(10)
In [8]:
arr
Out[8]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [9]:
arr[5]
Out[9]:
5
In [10]:
arr[5:8]
Out[10]:
array([5, 6, 7])
In [11]:
arr[5:8]=12  #数值被传递给了整个切片
In [12]:
arr
Out[12]:
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
In [13]:
arr[[2,3,5]]  #实现跳着取值
Out[13]:
array([ 2,  3, 12])

数组的切片是原数组的视图,这意味着数组并不是被复制,任何对于数组的修改都会反映到原数组上

In [14]:
arr_slice=arr[5:8]
In [15]:
arr_slice
Out[15]:
array([12, 12, 12])

当改变arr_slice,变化也会体现在原数组上

In [16]:
arr_slice[1]=1234
In [17]:
arr
Out[17]:
array([   0,    1,    2,    3,    4,   12, 1234,   12,    8,    9])

不写切片值[:]将会引用数组的所有值

In [18]:
arr_slice[:]=64
In [19]:
arr
Out[19]:
array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

在一个二维数组中,每个索引值对应的元素不再是一个值,而是一个一维数组

In [20]:
arr2d=np.array([[1,2,3],[4,5,6],[7,8,9]])
In [21]:
arr2d[2]
Out[21]:
array([7, 8, 9])

我们可以通过传递索引的都好分隔列表取选择单个元素,下面两种方法都可以取出矩阵中的元素

In 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值