使用整数数组进行数据索引——索引是个数组
举例说明,比如现在有一个这样的二维数组:
arr = np.empty((8,4))
for i in range(8):
arr[i]=i # 给每行赋值,赋给行中的每个元素
arr
# array([[0., 0., 0., 0.],
# [1., 1., 1., 1.],
# [2., 2., 2., 2.],
# [3., 3., 3., 3.],
# [4., 4., 4., 4.],
# [5., 5., 5., 5.],
# [6., 6., 6., 6.],
# [7., 7., 7., 7.]])
然后,现在想要按顺序提取二维数组的第3、1、4行:
arr[[2,0,3]]
# array([[2., 2., 2., 2.],
# [0., 0., 0., 0.],
# [3., 3., 3., 3.]])
看起来有点复杂,其实在使用单个数字作为索引提取二维数组时(如 arr[1])被提取的就是某一行数组,索引查找的是第几行数据。
而 神奇数组 将这一功能延申,用数组作为索引,一次提出若干行数据,并再次拼成一个二维数组。
当然,和正常索引一样,这里的整数数组索引中,如果使用负数,那么会反向提取行。
进一步,如果我不满足于只提取二维数组的某一行,我还想便捷地提取二维数组的具体“坐标”,也可以用神奇索引做到。
比如现在想提取坐标为(0,1) (2,3) (3,0) (6,2)的元素:
arr2 = np.arange(32).reshape(8,4)
arr2
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15],
# [16, 17, 18, 19],
# [20, 21, 22, 23],
# [24, 25, 26, 27],
# [28, 29, 30, 31]])
arr2[[0,2,3,6],[1,3,0,2]]
# array([ 1, 11, 12, 26])
这是上述操作的延续,神奇索引的第一个整数数组是选取行,如果放入第二个数组,那么就能选取对应列。
很自然,这样提取的结果就变成了一维数组。
如果你还记得线性代数的基础运算,一定记得 转置T 这一操作
arrT = np.arange(15).reshape(3,5)
arrT
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14]])
在python中,由于多维数组应用广泛,这一操作被超级简化为:
arrT.T
# array([[ 0, 5, 10],
# [ 1, 6, 11],
# [ 2, 7, 12],
# [ 3, 8, 13],
# [ 4, 9, 14]])
当进行矩阵计算时,可能会经常进行一些特定操作,比如,当计算矩阵外积会使用np.dot:
np.dot(arrT.T,arrT)
# array([[125, 140, 155, 170, 185],
# [140, 158, 176, 194, 212],
# [155, 176, 197, 218, 239],
# [170, 194, 218, 242, 266],
# [185, 212, 239, 266, 293]])
关于矩阵运算:矩阵的内积、外积_矩阵内积_摩霄志在潜修羽的博客-CSDN博客
通用函数,也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。
arr = np.arange(10)
arr
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.sqrt(arr)
# array([0. , 1. , 1.41421356, 1.73205081, 2. ,
# 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
np.exp(arr)
# array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
# 5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
# 2.98095799e+03, 8.10308393e+03])
np.square(arr)
# array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81], dtype=int32)
x = np.random.randn(8)
y = np.random.randn(8)
x
# array([-1.69218562, -0.61751156, 0.11570706, 1.02573863, 1.12828294,
# -1.11654258, -0.7676222 , -0.92078126])
y
# array([ 1.64569477, -1.03458824, -1.17575001, 2.33113228, -0.05221603,
# 0.47681856, -1.62747072, -1.47204685])
np.maximum(x,y)
# array([ 1.64569477, -0.61751156, 0.11570706, 2.33113228, 1.12828294,
# 0.47681856, -0.7676222 , -0.92078126])
np.add(x,y)
# array([-0.04649085, -1.6520998 , -1.06004296, 3.35687091, 1.07606691,
# -0.63972402, -2.39509292, -2.39282811])
其他常见二元函数:
返回一个浮点值数组的小数部分和整数部分(可以用两个参数来接这两个数组)
np.modf(x)
# (array([-0.69218562, -0.61751156, 0.11570706, 0.02573863, 0.12828294,
# -0.11654258, -0.7676222 , -0.92078126]),
# array([-1., -0., 0., 1., 1., -1., -0., -0.]))
通用函数都能接收一个可选参数out(如果有两个返回值就可以放两个可选参数),允许对数组按位置操作:
out1=np.random.randn(8)
out2=np.random.randn(8)
np.modf(x,out2,out1)
out1
# array([-1., -0., 0., 1., 1., -1., -0., -0.])
out2
# array([-0.69218562, -0.61751156, 0.11570706, 0.02573863, 0.12828294,
# -0.11654258, -0.7676222 , -0.92078126])
当然,尺寸和数据格式需要匹配才行