Numpy库

NumPy之于数值计算特别重要的原因之一,是因为它可以高效处理大数组的数据。这是因为:

  • NumPy是在一个连续的内存块中存储数据,独立于其他Python内置对象。NumPy的C语言编写的算法库可以操作内存,而不必进行类型检查或其它前期工作。比起Python的内置序列,NumPy数组使用的内存更少。
  • NumPy可以在整个数组上执行复杂的计算,而不需要Python的for循环。

一、创建ndarray

(1)arange()函数:

调用格式:arange(start,stop,step)
start:间隔开始。间隔包括此值,默认开始值为0。
stop:间隔结束。间隔不包括此值。
step:间隔步长。
例子:
import numpy as np
>>> np.arange(3)
#array([0, 1, 2])
>>> np.arange(3.0)
#array([ 0.,  1.,  2.])
>>> np.arange(3,7)
#array([3, 4, 5, 6])
>>> np.arange(3,7,2)
#array([3, 5])

   arr = np.arange(32).reshape((8, 4))

(2)random模块:随机数生成

         rand():函数根据给定维度生成[0,1)之间的数据,包含0,不包含1。如:>>> data1 = np.random.rand(2,3)

         randn():函数根据给定维度生成一个或一组样本,具有标准正态分布。如:>>>data2 =  np.random.randn(2,3)

  (3)  每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数组数据类型的对象)属性。         

>>> data.shape
#(2,3)
>>> data.dtype
#float64
>>> data.ndim
#2

(4)创建数组函数

         array函数:它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的NumPy数组。

>>> data1 = [1,2,3,4]
>>> data2 = [[1,3,4,6],[2,4,6,9]]
>>> data_arr1 = np.array(data1)
>>> data_arr2 = np.array(data2)
>>> print(data_arr1)
>>> print(data_arr2)
[1 2 3 4]

[[1 3 4 6]
[2 4 6 9]]

       除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组。

二、ndarray的数据类型

       dtype(数据类型)是一个特殊的对象,它含有ndarray将一块内存解释为特定数据类型所需的信息:

  arr1 = np.array([1, 2, 3], dtype=np.float64)

      可以通过ndarray的astype方法明确地将一个数组从一个dtype转换成另一个dtype:

>>> arr = np.array([1, 2, 3, 4, 5])
>>> arr.dtype

dtype('int64')

>>> float_arr = arr.astype(np.float64)
>>> float_arr.dtype

dtype('float64')

调用astype总会创建一个新的数组(一个数据的备份),即使新的dtype与旧的dtype相同。

三、numpy数组的运算

        数组很重要,因为它使你不用编写循环即可对数据执行批量运算。NumPy用户称其为矢量化(vectorization)。大小相等的数组之间的任何算术运算都会将运算应用到元素级。

 

arr = np.array([[2,4,6,8],[1,4,7,3]])
print(arr)
print(arr*arr)
print(arr-arr)

[[2 4 6 8]
[1 4 7 3]]


[[ 4 16 36 64]
[ 1 16 49 9]]


[[0 0 0 0]
[0 0 0 0]]

        数组与标量的算术运算会将标量值传播到各个元素:

print(1/arr)
print(arr**0.5) 

[[0.5 0.25 0.16666667 0.125 ]
[1. 0.25 0.14285714 0.33333333]]

[[1.41421356 2. 2.44948974 2.82842712]
[1. 2. 2.64575131 1.73205081]]

     大小相同的数组之间的比较会生成布尔值数组:

arr1 = np.array([[2,4,9,12],[2,4,7,3]])
print(arr<arr1) 

[[False False True True]
[ True False False False]]

 四基本的索引和切片

        当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传播(也就说后面将会讲到的“广播”)到整个选区。跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。

        如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如arr[5:8].copy()。

(1)切片索引

arr = np.array([0,  1,  2,  3,  4, 64, 64, 64,  8,  9])
print(arr)
print(arr[1:6])
arr2d = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(arr2d)
print(arr2d[1])
print(arr2d[:2])
print(arr2d[:,:2])

 

[ 0 1 2 3 4 64 64 64 8 9]
[ 1 2 3 4 64]


[[1 2 3]
[4 5 6]
[7 8 9]]


[4 5 6]


[[1 2 3]
[4 5 6]]


[[1 2]
[4 5]
[7 8]]

对切片表达式的赋值操作也会被扩散到整个选区

(2)布尔型索引

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7,4)
print(names=='Bob')
print(data[names == 'Bob'])
#布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数混合使用
print(data[names == 'Bob',2:])
print(data[names == 'Bob',2])
print(data[names != 'Bob'])
#~操作符用来反转条件很好用
print(data[~(names == 'Bob')])
#Python关键字and和or在布尔型数组中无效。要使用&与|。
print((names == 'Bob')|(names == 'Will'))
print(data[(names == 'Bob')|(names == 'Will')])
#将data中的所有负值都设置为0
data[data<0]=0
print(data) 

[ True False False True False False False]


[[ 0.56947009 -0.61103578 -0.83001537 -1.03831856]
[-0.72723257 0.72598221 0.36284245 -1.6662993 ]]


[[-0.83001537 -1.03831856]
[ 0.36284245 -1.6662993 ]]


[-0.83001537 0.36284245]


[[ 0.8576646 1.37711165 -0.97693128 0.70626358]
[ 0.5193894 -1.07092886 -1.60173978 0.03837702]
[ 0.25293635 0.09664311 2.20232715 0.44455463]
[-0.4188091 -1.62252806 -1.435578 1.18620694]
[-0.78747297 1.35354608 0.20774316 0.84989592]]


[[ 0.8576646 1.37711165 -0.97693128 0.70626358]
[ 0.5193894 -1.07092886 -1.60173978 0.03837702]
[ 0.25293635 0.09664311 2.20232715 0.44455463]
[-0.4188091 -1.62252806 -1.435578 1.18620694]
[-0.78747297 1.35354608 0.20774316 0.84989592]]


[ True False True True True False False]


[[ 0.56947009 -0.61103578 -0.83001537 -1.03831856]
[ 0.5193894 -1.07092886 -1.60173978 0.03837702]
[-0.72723257 0.72598221 0.36284245 -1.6662993 ]
[ 0.25293635 0.09664311 2.20232715 0.44455463]]


[[0.56947009 0. 0. 0. ]
[0.8576646 1.37711165 0. 0.70626358]
[0.5193894 0. 0. 0.03837702]
[0. 0.72598221 0.36284245 0. ]
[0.25293635 0.09664311 2.20232715 0.44455463]
[0. 0. 0. 1.18620694]
[0. 1.35354608 0.20774316 0.84989592]]

(3)花式索引

利用整数数组进行索引,花式索引跟切片不一样,它总是将数据复制到新数组中。

 

arr = np.empty((8,4))
for i in range(8):
    arr[i] = i
print(arr)
print(arr[[1,2,4,0]]) 

[[1. 1. 1. 1.]
[2. 2. 2. 2.]
[4. 4. 4. 4.]
[0. 0. 0. 0.]]

四、快速的元素级数组函数

 

 

五、利用数组进行数据处理

 numpy.where(cond, xarr, yarr)函数是三元表达式x if condition else y的矢量化版本。np.where的第二个和第三个参数不必是数组,它们都可以是标量值。在数据分析工作中,where通常用于根据另一个数组而产生一个新的数组。

arr = np.random.randn(3,4)
print(arr)
cond = arr>0
print(cond)
narr = np.where(cond,2,arr)
print(narr)

  

[[ 0.38456504 1.61308418 2.38985258 0.23335973]
[-1.43672573 -1.29377899 -0.27695053 1.01830536]
[-1.37364818 -1.17896878 0.32970775 1.34110048]]


[[ True True True True]
[False False False True]
[False False True True]]


[[ 2. 2. 2. 2. ]
[-1.43672573 -1.29377899 -0.27695053 2. ]
[-1.37364818 -1.17896878 2. 2. ]]

 

数学和统计方法

 

 

arr = np.random.randn(5, 4)
arr.mean()
arr.sum()
arr.cumsum()
arr.cumprod()

排序

顶级方法np.sort返回的是数组的已排序副本,而就地排序则会修改数组本身。  

arr = np.random.randn(6)
arr.sort()

唯一化

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
np.unique(names)

  

 
posted @ 2019-07-03 09:33  雪舞飞扬2019  阅读(305)  评论(0编辑  收藏  举报