Numpy基础 | 一步一步跟我学Phython(四)

  • 1.本系列基于新生大学课程《Python编程&数据科学入门》和公开的参考资料;
  • 2.文章例子基于python3.6,使用Windows系统(除了安装,其余基本没有影响);
  • 3.我是纯小白,所以,错误在所难免,体系会逐渐成熟,我会经常进行更新;如果您发现了错误,也烦请帮我指出来,在此先谢过了。

Numpy是Python的一个基础包,它的全名是Numercial Python,是Python高性能科学计算和数据分析的关键所在,也是Python如此成功的一个重要原因。

使用Numpy可以实现下面这些功能:

  • 任意维度的数组
  • 异常高效快速的运算
  • 线性代数和随机数的生成
  • 可集成C、C++以及Fortran等语言,提供API接口

总之,Numpy功能强大,是大数据和人工智能的必修课。

文章主要内容如下:

  • 数组对象的定义
  • 创建数组的方法
  • 数组的属性
  • 数组的索引和切片
  • 数组的基本数据类型
  • 数组的运算
  • 数组的输出
  • 数组的统计方法
  • 一个数组的逻辑运算函数

数组对象的定义

Numpy的核心对象是数组(Ndarray),ndarray 是一个通用的同构多维数据容器。
有两点需要注意:

  • 第一,所有元素都必须是相同类型;
  • 第二,数组可以是无限维度。
import Numpy as np  #引入Numpy库,并简写为np

一维数组有点像列表,二维数组像表格。但数组中的元素这能是同一种数据类型,这是其高效运行的关键因素。更简洁,更高效。

创建数组的方法

1)通过array函数

数组接受一切序列对象,然后通过函数产生一个新的含有数据的Numpy数组。

** 示例1

import numpy as np #在使用Numpy前,必须导入这个库。
list1 = [3, 4, 5.5, 9]
array1 = np.array(list1)
array1

输出如下:

array([ 3. , 4. , 5.5, 9. ])

** 示例2

import numpy as np #在使用Numpy前,必须导入这个库。
list2 = [[1,3,5,7],[2,4,6,8]]
array2 = np.array(list2)
array2

输出如下:

array([[1, 3, 5, 7],
[2, 4, 6, 8]])

2)用zeros和ones函数快速创建数组

  • 分别创建制定长度或形状的全0和全1的数组
np.zeros(12)

输出如下:

array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
  • 用数组创建多维函数:
np.ones((2,4))

输出如下:

array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])

3)用empty函数创建

  • 可以创建一个没有具体值的数组。
    注意,不是空值,而是一些未初始化的垃圾值。
np.empty((3,2))

输出如下:

array([[ 2.49914608e-47, 1.39371627e+06],
[ 4.84026180e+15, 1.49082394e-76],
[ 0.00000000e+00, 0.00000000e+00]])

4)arange函数

  • 可以创建一定范围的数组,类似于range函数。它的语法仍然是arange(sart, end, step)
np.arange(12)

输出如下:

array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

np.arange(2, 10, 2)

输出如下:

array([2, 4, 6, 8])
  • 结合reshape可以创建多维数组
np.arange(10).reshape(2,5)

输出如下:

array([0,1,2,3,4],
[5,6,7,8,9])

5)用ones_like、zeros_like和empty_like

可以根据一个数组创建一个全1、全0和只分配空间的数组。

np.zeros_like(array2) # 以前已经赋过值的函数

输出如下:

array([[0, 0, 0, 0],
[0, 0, 0, 0]])

6)eye函数

可以创建一个正方的N*N的矩阵(二维数组);

  • 用random函数。可以生成一些随机的数据源。
np.random.randn(3,5)

输出如下:

array([[ 0.67201938, 1.26250439, -0.75518549, -0.96637329, 0.20020499],
[ 1.46767699, 0.03292811, 1.24308473, 0.19780962, -2.23047114],
[ 1.2278105 , 0.88424898, -2.11662492, 0.30141536, -1.32447466]])

数组的属性

每个数组ndarray都有shape和dtype,也就是形状和类型。

  • ndarray.ndim :数组的维数。

每一个线性的数组称之为轴(axis),秩(rank)就是描述轴的数量。维数等于秩。

array2.ndim

输出如下:

2
  • ndarray.shape :数组的形状。
array2.shape

输出如下:

(2,4)

它可以改变数组的形状。

import numpy as np
arr01 = np.arange(1,16)
arr01.shape = (3,5)
arr01

输出

array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])

它返回一个元组,这个元组就是表示各个维度的大小。

  • ndarray.size:数组元素的个数。

等于shape属性中元组元素的乘积。

array2.size

输出如下:

8
  • ndarray.dtype:数组元素的类型。
array2.dtype

输出如下:

dtype('int32')
  • ndarray.itemsize:数组中每个元素的字节大小。
array2.itemsize

输出如下:

4

Numpy的索引和切片

索引是选取数据的一个元素,维度降低;而切片是选取数据的子集,维度保持不变,只是空间变小了。

  • 一维数组,使用[]进行,与列表是一样的。
    比如:arr[3],arr[2:3]
  • 二维数组,使用两个参数,逗号隔开,先索引列,再索引行,用[]表示。
arr3 = np.empty((4,5))
arr3[3,2]
arr3[2:3,2]

索引得到的是第4列(列3),而切片得到的是第3至第4列,所以输出如下:

array([ 5.56218858e+180])
1.9497344566623563e+160

注意:得到的这两个值的意义是不同的。第一个是一个索引,是一个元素值,而第二个是一个二维数组,只是只有一行一列而已。如果想要得到一个元素的值,要采用arr3[2:3,2][0]的方法。

三维及以上维度的数组的也是类似的。

  • 布尔型索引
    Numpy允许用另一个数组的布尔值作为数组的索引。
    比如:
    item1 = np.array(['book', 'write', 'run', 'program', 'run', 'book'])
    再使用随机数生成一个数组:
    data = np.random.randn(6,4)

先对item1数组进行布尔运算,得到一个布尔型的数组
item1 == 'book'

array([ True, False, False, False, False, True], dtype=bool)

这个布尔型的数组就可以用于数组索引。
data[item1 == 'book']
输出的值是对应这个布尔型进行索引的。所以,第一行和最后一行被输出:

array([[-0.90089307, 0.36295259, -1.67628201, -0.39765334],
[-0.49065895, 0.9847132 , -1.07655711, -1.25794759]])

注意:布尔型数组的长度必须和被索引的轴的长度保持一致。

  • 数组的索引和切片是原始数组的视图
    原始数组的视图,也就是说原来的数组不是被复制了,而是被引用了,任何改变都会影响到原来的数组。
score = np.array([59, 65, 70, 88, 49, 98])
score[4] = 60
score1 = score[0:2]
score1[0] = 60
score

输出如下:

array([60, 65, 70, 88, 60, 98])

两个值都被修改为60了。

如果不想改变arr2里面的值,可以用.copy方法

score2 = score[0:2].copy()
score2[0] = 59
score2

输出如下:

array([59, 65])
score

输出的是

array([60, 65, 70, 88, 60, 98])

也就是说切片score2里面的60被修改为59,但是原来的数组score并没有被修改。

数组的基本数据类型

与Python的数据类型稍微有点差异。

  • 用dtype查询数组的数据类型
  • 用astype可以将数组类型进行转换。
  • 将dtype和astype结合,将一个数组的类型装换为与另一个数组的类型相同

例1

arr = np.array([2,34,5,9])
arr.dtype

输出如下:

dtype('int32'

例2

arr_f = arr.astype(np.float64)
arr_f.dtype

输出如下:

dtype('float64')

注意:用astype函数会立马创建出一个数组,即使和之前的相同。而不会改变之前的数组的类型。


# coding: utf-8
import numpy as np
arr = np.arange(10)
arr.dtype # 得到类型的结果‘int32’

arr.astype(np.float) # 转换为float格式

array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])


arr.dtype # 查询arr的类型

结果仍然是int32

dtype('int32')

例子3

arr_f = arr.astype(np.float64)
arr_f.dtype

输出如下:

dtype('float64')
Numpy基础 | 一步一步跟我学Phython(四)_第1张图片

数组的运算

  • 数组与单个数之间的运算

对数组进行任何算数运算,都会对数组内所有的元素进行运算。这通常被叫做矢量化(vectorization)。

比如:

arr3 = np.zeros((4, 3, 3))
arr4 = arr3 + 1
arr4

输出如下:

array([[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],

[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],

[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]],

[[ 1., 1., 1.],
[ 1., 1., 1.],
[ 1., 1., 1.]]])

所有的元素都+1。

  • 相同的数组还可以直接运算
    比如:
arr5 = np.arange(10)
arr6 = np.ones(10)

这是两个一维的数组。两者相加:

arr5+arr6

输出如下:

array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])

每一个元素都对应相加了。

  • 不同维度的数组也可以运算
    运算的时候,低维度的数组先要将自己广播为一个高维度的数组,再按照同维度数组进行处理。
print(np.ones((2,10)) +arr5)

arr5只有一个维度,而np.ones((2,10))有两个维度。所以,在运算的时候,arr5先按照np.ones((2,10))的第二维度的长度将维度复制,np.ones((2,10))的第二维有2行,所以,arr5复制1份,在相加时,它实际使用的是:

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

所以,输出如下:

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

数组的输出

一维数组被打印成行,二维数组组成矩阵,三维以上数组组成矩阵列表。

a = np.arange(6)
print(a)

输出如下:

[0 1 2 3 4 5]
b = np.arange(12).reshape(4,3)
print(b)

输出如下:

[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
c = np.arange(24),reshape(2,3,4)
print(c)

输出如下:

[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]

如果一个数组的长度太长,Numpy会自动把中间的省略,只打印两端的内容。

d = np.arange(10000).reshape(100, 100)
print(d)

输出如下:

[[ 0 1 2 ..., 97 98 99]
[ 100 101 102 ..., 197 198 199]
[ 200 201 202 ..., 297 298 299]
...,
[9700 9701 9702 ..., 9797 9798 9799]
[9800 9801 9802 ..., 9897 9898 9899]
[9900 9901 9902 ..., 9997 9998 9999]]

可以通过printoptions参数来让Numpy强制打印整个数组。
set_printoptions(threshold = 'nan')

数组的统计方法

np.sum(ndarray, axis = n),求和。

arr01 = np.arange(15).reshape(3,5)
np.sum(arr01)
arr01
np.sum(arr01, 1)
arr01

输出如下:

7.0
array([ 5., 6., 7., 8., 9.])

不指定某行或某列的,对所有元素求值。

另外,还有其他的一些统计方法:

  • mean,计算平均值。
  • max,计算最大值。
  • min,计算最小值

数组的逻辑运算函数

numpy.where函数非常神奇,它是x if condition else y的矢量化版本。

arr = np.random.randn(10) #生成一个一维数组。
arr

任务:把小于0的负数改成- 1,把大于0的改成1。

如果采用if函数,可以用这样的方法:

for i in range(10):
    if arr[i]>0:
        arr[i]=1
    else:
        arr[i]= -1
    
arr

用np.where则简单的多。

np.where(arr >0, 1 , -1)

生成随机数

用numpy.random可以快速生成随机数,它比Python内置的random函数快了不止一个数量级。

samples = np.random.normal(size=(4,4)) # normal函数是一个生成标准正态分布的随机函数。

random还有很多其他的函数:

Numpy基础 | 一步一步跟我学Phython(四)_第2张图片
random函数.jpg


知识本身不是力量,“知识+持续的行动”才是!

我是陶肚,每天陪你读点书。如果喜欢,请帮忙点赞或分享出去。

你可能感兴趣的:(Numpy基础 | 一步一步跟我学Phython(四))