Numpy ndarray:多维数组对象

本文深入讲解NumPy数组的创建、属性、算术运算、索引与切片、转置及布尔索引等核心功能,是Python数值计算入门的必备指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NumPy是目前python数值计算中最为重要的基础包,它的核心特征之一就是N-维数组对象——ndarray,这篇博文主要来介绍这个多维同类数据容器。

生成ndarray

ndarray包含的每种元素均为同种类型。生成数组的函数有很多,这里我介绍几种常用的。

#先导入NumPy
import NumPy as np
  1. np.array()参数是序列型对象,自动推断输入数据的数据类型,在创建的时候可以指定维度ndmin和数值类型dtype。
np.array("love")

output:

array('love', dtype='<U4')
  1. np.zeros()参数是关于d0,d1,d2,dn的元组,返回全0数组
np.zeros((2,3,4))

output:

array([[[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]],

       [[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]]])
  1. np.ones()参数是关于d0,d1,d2,dn的元组,返回全1数组
np.ones((2,3,4))

output:

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. np.empty()参数是关于d0,d1,d2,dn的元组,返回没有初始化数值的空数组
np.empty((2,1,3))

output:

array([[[0., 0., 0.]],

       [[0., 0., 0.]]])
  1. np.arange()内建函数range的数组版。参数为起始值,终止值(取不到),步长
np.arange(2,15,3)

output:

array([ 2,  5,  8, 11, 14])
  1. np.linspace()。参数为起点值,终止值(取到),元素个数。
np.linspace(10,20,5)
np.linspace(0,1,10,endpoint=False)

output:

array([10. , 12.5, 15. , 17.5, 20. ])
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
  1. np.logspace()。与上面的np.linspace()相似
np.logspace(0,2,20)

output:

array([  1.        ,   1.27427499,   1.62377674,   2.06913808,
         2.6366509 ,   3.35981829,   4.2813324 ,   5.45559478,
         6.95192796,   8.8586679 ,  11.28837892,  14.38449888,
        18.32980711,  23.35721469,  29.76351442,  37.92690191,
        48.32930239,  61.58482111,  78.47599704, 100.        ])

8.np.eye()返回对角线为1,其余为0的二维数组,第一个参数为numbers of rows,第二个参数为numbers of columns,默认等于第一个参数的值。

np.eye(5)

output:

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

接下来介绍几个ndarray的属性

#生成随机数组,(0,1)标准正态分布随机数
data = np.random.randn(2,3)
data
#数组每一维度的数量
data.shape
#数组类型
data.dtype
#数组维数
data.ndim

output:

array([[ 0.71552267,  1.12464515,  0.84971133],
       [-0.43746949,  1.12846303, -0.29032458]])
       
(2, 3)

dtype('float64')

2

我们可以使用astype方法来转换数组的数据类型,值得注意的是,该方法总是会生成一个新的数组。

data.astype(np.int32)
data

output:

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

array([[ 0.71552267,  1.12464515,  0.84971133],
       [-0.43746949,  1.12846303, -0.29032458]])

Numpy数组算术

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

arr = np.array([[1,2,3],[4,5,6]])
arr * arr
arr - arr
1/arr
arr * 0.5
#同尺寸数组之间的比较,会产生一个布尔值数组
arr2 = np.array([[2,4,6],[1,2,3]])
arr2 > arr

out:

array([[ 1,  4,  9],
       [16, 25, 36]])

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

array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])

array([[0.5, 1. , 1.5],
       [2. , 2.5, 3. ]])

array([[ True,  True,  True],
       [False, False, False]])

索引与切片

  1. 一维数组的索引与切片,与python列表的用法有点相似
#生成一维数组
arr = np.arange(10)
arr

Out:

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#与列表不同,通过下标范围获取的新的数组是原始数组的一个视图,与原始数组共享一块数据空间,对于视图的修改会体现到原数组上
arr[5:8]=12
arr

Out:

array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])
#改变aar1时,原数组也会进行改变
arr1 = arr[5:8]
arr1
arr1[:] = 24
arr

Out:

array([12, 12, 12])

array([ 0,  1,  2,  3,  4, 24, 24, 24,  8,  9])
#数组切片的拷贝可以利用.copy()
arr11 = arr[5:8].copy()
arr11
arr11[:] = 48#改变aar11时,原数组不会进行改变
arr

Out:

array([24, 24, 24])

array([ 0,  1,  2,  3,  4, 24, 24, 24,  8,  9])
  1. 二维数组的索引,二维数组每个索引值对应的元素是一个一维数组
#生成一个二维数组
arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
#索引第三行
arr2d[2]
#索引第三行,第一列
arr2d[2][0]
#索引第三行,第一列
arr2d[2,0]
#索引第三行和第一行
arr2d[[2,0]]

Out:

array([7, 8, 9])
7
7
array([[7, 8, 9],
       [1, 2, 3]])
  1. 二维数组的切片
#生成二维数组
arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
#选择前两行
arr2d[:2]
#选择前两行的第二列和第三列
arr2d[:2,1:]

Out:

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

array([[2, 3],
       [5, 6]])

对切片表达式赋值时,整个切片都会重新赋值

arr2d[:2,1:] = 0
arr2d

Out:

array([[1, 0, 0],
       [4, 0, 0],
       [7, 8, 9]])
  1. 三维数组的索引
#三维数组的索引,2*2*3的数组
arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
arr3d[0]
arr3d[0,0]
arr3d[0][0]

Out:

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

array([1, 2, 3])

array([1, 2, 3])
  1. 布尔索引
#生成一维数组names
names = np.array(["aa","bb","aa","dd","ee","aa","gg"])
#利用randn函数生成随机正态分布的二维数据data
data = np.random.randn(7,4)
names
data

names == "aa"
#利用布尔值进行索引
data[names == "aa"]

Out:

array(['aa', 'bb', 'aa', 'dd', 'ee', 'aa', 'gg'], dtype='<U2')

array([[ 0.7416918 ,  0.88800978,  0.68197079, -0.53014663],
       [-0.18299815, -0.48641017,  0.90295139,  2.4727419 ],
       [-0.52766455, -0.36830999,  0.45128251,  0.48811192],
       [ 0.71607019,  1.63065359, -0.71081597, -2.88685402],
       [ 0.59853369,  0.03907715, -0.21053569,  0.18792567],
       [-0.1643565 ,  0.97845669, -0.92076973, -1.29995933],
       [ 0.68262773,  0.61233984, -1.23746087, -0.50847237]])

array([ True, False,  True, False, False,  True, False])

array([[ 0.7416918 ,  0.88800978,  0.68197079, -0.53014663],
       [-0.52766455, -0.36830999,  0.45128251,  0.48811192],
       [-0.1643565 ,  0.97845669, -0.92076973, -1.29995933]])
#可以使用!=或在条件表达式前使用~对条件取反
data[names != "aa"]
data[~(names == "aa")]
cond = names == "aa"
data[~cond]

Out:

array([[-0.18299815, -0.48641017,  0.90295139,  2.4727419 ],
       [ 0.71607019,  1.63065359, -0.71081597, -2.88685402],
       [ 0.59853369,  0.03907715, -0.21053569,  0.18792567],
       [ 0.68262773,  0.61233984, -1.23746087, -0.50847237]])

array([[-0.18299815, -0.48641017,  0.90295139,  2.4727419 ],
       [ 0.71607019,  1.63065359, -0.71081597, -2.88685402],
       [ 0.59853369,  0.03907715, -0.21053569,  0.18792567],
       [ 0.68262773,  0.61233984, -1.23746087, -0.50847237]])

array([[-0.18299815, -0.48641017,  0.90295139,  2.4727419 ],
       [ 0.71607019,  1.63065359, -0.71081597, -2.88685402],
       [ 0.59853369,  0.03907715, -0.21053569,  0.18792567],
       [ 0.68262773,  0.61233984, -1.23746087, -0.50847237]])
#可以对多个布尔条件进行联合,使用数学操作符|和&
mask = (names == "aa")|(names == "bb")
mask
data[mask]
#使用布尔值选择数据时,总是生成数据的拷贝

Out:

array([ True,  True,  True, False, False,  True, False])

array([[ 0.7416918 ,  0.88800978,  0.68197079, -0.53014663],
       [-0.18299815, -0.48641017,  0.90295139,  2.4727419 ],
       [-0.52766455, -0.36830999,  0.45128251,  0.48811192],
       [-0.1643565 ,  0.97845669, -0.92076973, -1.29995933]])

数组转置

#数组转置和换轴
arr = np.arange(15).reshape((3,5))
arr
arr.T

Out:

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

array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])
arr = np.random.randn(6,3)
arr
np.dot(arr.T,arr)#用来计算矩阵内积

Out:

array([[ 0.58847723,  0.84348489,  1.42054432],
       [ 0.95521876, -1.13381903, -0.60993457],
       [-0.19601102,  0.40465638, -1.04277897],
       [-0.03255321,  0.40138796,  0.27147854],
       [-0.55308299, -0.57412833, -0.8741011 ],
       [ 0.51149413, -0.12046626,  0.41461565]])

array([[ 1.86575541, -0.42313431,  1.14441965],
       [-0.42313431,  2.66600688,  2.02866315],
       [ 1.14441965,  2.02866315,  4.48701381]])

transpose方法和swapaxes方法都没有对数组进行复制,返回的是数据的视图,原数组不变

#transpose方法可以接收包含轴编号的元组,用于置换轴,使用该方法后,原数组不变
arr = np.arange(16).reshape((2,2,4))
arr
arr.transpose((1,0,2))
arr

Out:

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

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

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

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
#swapaxes方法接收一对轴编号作为参数,并对轴进行调整用于重组数组
arr
arr.swapaxes(1,2)
arr

Out:

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

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

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

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])

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

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

关于ndarray多维数组对象还有很多其他有意思的知识点,大家可以找一些相关书籍和教程继续学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值