重学 Python!一文带你上手精通 NumPy

虽然深入理解NumPy对于大部分数据分析应用并不是必需的,但是精通基于数组的编程和思考是成为Python科学计算专家的重要一步。本文将带你上手精通 NumPy!

1、生成 ndarray

生成数组最简单的方式就是使用 array 函数。array 函数接收任意的序列型对象(当然也包括其他的数组),生成一个新的包含传递数据的 NumPy 数组。如下将列表转为一维数组

import numpy as np
data = np.array([[1, 2, 3]])
data

# Output
# array([[1, 2, 3]])

当然我们也可以将二维列表转为二维数组

import numpy as np
data = np.array([[1, 2, 3],[4, 5, 6]])
data

# Output
# array([[1, 2, 3], [4, 5, 6]])

除了 np.array,还有很多其他函数可以创建新数组。例如,给定长度及形状后,zeros 可以一次性创造全0数组,使用 ones 可以一次性创造全1数组

import numpy as np
np.zeros(5)
# Output
# array([0., 0., 0., 0., 0.])

np.ones(5)
# Output
# array([1., 1., 1., 1., 1.])

同时可以使用 arange 生成等间隔数值序列,它的基本用法和参数如下:

numpy.arange([start], stop[, step], dtype=None)
  • start(可选):序列的起始值,默认为 0。
  • stop:序列的结束值(不包括该值)。
  • step(可选):步长,默认为 1。表示每两个相邻值之间的差。
  • dtype(可选):输出数组的数据类型。如果未指定,NumPy 会根据输入的值自动推断。

例子如下

import numpy as np
np.arange(2, 10, 2)

# Output
# array([2, 4, 6, 8])
2、ndarray 的数据类型

ndarray 中的数据类型用 dtype 表示,ndarray 需要为某一种类型数据所申明的内存块信息,numpy 会在数据初始化的时候根据初始的数据,推测数据类型

import numpy as np
data = np.array([[1, 2, 3],[4, 5, 6]])
data.dtype  # dtype('int32')

我们也可以在初始化的时候,制定数据类型,如下所示

import numpy as np
data = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float64)
data.dtype  # dtype('float64')

如果数组的类型不是我们想要的,我们可以使用 astype 方法显式地转换数组的数据类型

import numpy as np
arr = np.array([1, 2, 3]) # dtype('int32')

float_arr = arr.astype(np.float64)
float_arr.dtype # dtype('float64')
3、NumPy 数组算术

NumPy 数组之所以快有一个很重要的原因:它允许你进行批量操作而无须任何 for 循环,也即向量化!

任何在两个等尺寸数组之间的算术操作都应用了逐元素操作的方式,如下所示

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
arr * arr
# Output
# array([[ 1,  4,  9], [16, 25, 36]])

arr - arr
# Output
# array([[0, 0, 0], [0, 0, 0]])

带有标量计算的算术操作,会把计算参数传递给数组的每一个元素,如下所示

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
1 / arr
# Output
# array([[1. , 0.5, 0.33333333], [0.25, 0.2 , 0.16666667]])

同尺寸数组之间的比较,会产生一个布尔值数组,如下所示

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[6, 5, 4], [3, 2, 1]])
arr2 > arr
# Output
# array([[True, True, True], [ False, False, False]])
4、基础索引与切片

(1)数组的索引

可以使用数组的下标去获取单个元素的值,如下所示,有以下两种方式,其结果一样

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
arr[1,2]  # 6
arr[1][2] # 6

(2)数组切片

我们可以通过数组切片获取数组的子集,区别于Python的内建列表,数组的切片是原数组的视图。这意味着数据并不是被复制了,任何对于视图的修改都会反映到原数组上

arr = np.arange(10)
arr[2:5]
# Output
# array([2, 3, 4])

# 修改
arr[2:5] = 10
arr
# Output
# array([ 0,  1, 10, 10, 10,  5,  6,  7,  8,  9])

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

arr[:] = 10
arr
# Output
# array([10, 10, 10, 10, 10, 10, 10, 10, 10, 10])

Python 的这种视图的操作,主要是由于 NumPy 被设计成适合处理非常大的数组,你可以想象如果 NumPy 持续复制数据会引起多少内存问题。

如果你还是想要一份数组切片的拷贝而不是一份视图的话,你就必须显式地复制这个数组,例如arr[2:5].copy(),如下所示,copy 后的数组发生数值更改,但是原数组中的数值没有发生改变。

arr = np.arange(10)
arr_2 = arr[2:5].copy()
arr_2[:] = 10
arr
# Output
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

(3)多维数组的切片

NumPy 的多维数组切片功能非常强大,可以方便地访问和操作数组的特定部分,首先,我们可以创建一个多维数组(如二维数组)来进行切片操作:

import numpy as np

# 创建一个 3x4 的二维数组
arr = np.array([[1, 2, 3, 4],
                [5, 6, 7, 8],
                [9, 10, 11, 12]])

基本语法为 array[start:stop:step],其中 start 是起始索引,stop 是结束索引(不包括该索引),step 是步长

(3.1)切片单个维度

则访问特定行,如下所示

row = arr[1]  # 访问第二行
row

# Output
# array([5, 6, 7, 8])

访问特定列,如下所示

column = arr[:, 2]  # 访问第三列
column

# Output
# array([ 3,  7, 11])

(3.2)切片多个维度

访问特定子数组:

sub_array = arr[0:2, 1:3]  # 访问前两行和第二、第三列
sub_array

# Output
# array([[2, 3],
#        [6, 7]])

访问特定元素:

element = arr[2, 3]  # 访问第三行第四列的元素
element # 12

(4)使用步长切片

每隔一行和一列

sliced = arr[::2, ::2]  # 每隔一行和一列
sliced

# Output
# array([[ 1,  3],
#        [ 9, 11]])

(5)布尔索引

可以使用布尔数组进行切片,选择满足特定条件的元素:

bool_index = arr > 5  # 创建布尔索引
filtered = arr[bool_index]  # 选择大于 5 的元素
filtered
# Output
# array([ 6,  7,  8,  9, 10, 11, 12])

(6)花式索引

可以使用数组索引选择特定的行或列:

rows = np.array([0, 2])
cols = np.array([1, 3])
fancy_index = arr[rows, cols]  # 选择 (0,1) 和 (2,3) 的元素
fancy_index

# Output
# array([ 2, 12])
5、数组的转置和换轴

(1)数组的转置

转置是指将数组的行和列互换。对于二维数组,转置操作将第一维(行)变为第二维(列),第二维变为第一维。我们可以使用 .T 属性进展转置

import numpy as np
arr = np.array([[1, 2, 3],
                [4, 5, 6]])
arr.T
# Output
# array([[1, 4],
#        [2, 5],
#        [3, 6]])

除了 .T 属性,还可以使用 np.transpose() 函数进行转置。

np.transpose(arr)
# Output
# array([[1, 4],
#        [2, 5],
#        [3, 6]])

(2)数组的换轴

换轴是指在多维数组中交换任意两个轴的位置。对于高维数组,这种操作非常有用。我们可以使用 np.swapaxes(),如下所示

arr_3d = np.random.rand(2, 3, 4)

# 交换第 0 轴和第 1 轴
swapped = np.swapaxes(arr_3d, 0, 1)
swapped.shape 
# Output
# (3, 2, 4)

我们还可以使用 np.rollaxis(),其可以将指定的轴移动到目标位置。

# 将第 0 轴移动到第 2 个位置
rolled = np.rollaxis(arr_3d, 0, 2)
rolled.shape
# Output
# (3, 4, 2)
6、通用函数:快速的逐元素数组函数

通用函数,也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。某些简单函数接收一个或多个标量数值,并产生一个或多个标量结果,而通用函数就是对这些简单函数的向量化封装。我们简单举两个例子如下

import numpy as np
arr = np.arange(10)
np.max(arr) # 9
np.sum(arr) # 45

以下为常用的通用函数,大家可以根据需要的时候选择使用

如果你喜欢本文,欢迎点赞,并且关注我们的微信公众号:Python技术极客,我们会持续更新分享 Python 开发编程、数据分析、数据挖掘、AI 人工智能、网络爬虫等技术文章!让大家在Python 技术领域持续精进提升,成为更好的自己!

添加作者微信(coder_0101),拉你进入行业技术交流群,进行技术交流~

猜你喜欢

转载自blog.csdn.net/fengshi_fengshi/article/details/143352104