Numpy

Python学习笔记(2):Numpy基础之数组运算及索引和切片

2019-02-07  本文已影响1人  刘爱玛

目录
一、数组运算
二、数组索引和切片
1、切片索引
(1)一维数组
(2)二维数组
2、布尔型索引
3、花式索引

一、数组运算

本章主要讨论大小相同的数组运算(大小不同的数组运算又叫做广播,在后面章节介绍)。
数组之间的运算都会被应用到元素级。
示例:

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

arr-arr
输出:
array([[0, 0, 0],
       [0, 0, 0]])

1/arr
输出:
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667]])

arr ** 0.5
输出:
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974]])

二、数组索引和切片

1、切片索引

这里有一点与Java、C++等语言有明显不同,数组切片是原始数组的视图,这意味着数据不会被复制,视图上的任何修改都会直接反映到源数据上,如果需要一份数组的副本,需要显示的使用.copy()方法。

(1)一维数组:

arr = np.arange(10)
arr

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

arr[5]
输出:5

arr[5:8]
输出:array([5, 6, 7])

arr[5:8] = 12
arr
输出:array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

arr_slice = arr[5:8]
arr_slice[1] = 12345
arr

输出:array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,
           9])

arr_slice[:] = 64
arr

输出:array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

(2)二维数组:

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
输出:array([7, 8, 9])

arr2d[0, 2]
输出:3

arr2d[0][2]
输出:3

arr2d[0, 2]与arr2d[0][2]是一样的。二维数组的元素索引如下图:


二维数组的元素索引
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
old_values = arr3d[0].copy()
arr3d[0] = 42  #标量可以被赋值给切片
arr3d
输出:array([[[42, 42, 42],
        [42, 42, 42]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

arr3d[0] = old_values #数组也可以被赋值给切片
arr3d
输出:array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]])

以下这张图是几个切片索引的表达方式与对应的切片结果。


二维数组切片索引

代码示例:

arr2d
输出:array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

arr2d[:2]
输出:array([[1, 2, 3],
       [4, 5, 6]])

arr2d[:2, 1:]
输出:array([[2, 3],
       [5, 6]])

arr2d[1, :2]
输出:array([4, 5])

arr2d[2, :1]
输出:array([7])

arr2d[:, :1]
输出:array([[1],
       [4],
       [7]])

2、布尔型索引

可以通过一组布尔型数组来对数据型数组进行索引。

from numpy.random import randn
names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = randn(7, 4) #按照正态分布生成随机数
names
输出:array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')

data
输出:array([[-1.12065753,  1.46287992,  0.13695028, -1.89878434],
       [ 0.64101753,  0.76381041,  0.04337704, -0.69203921],
       [-1.42369882, -0.2431481 , -0.87991876, -0.09632813],
       [ 1.11837109, -0.61663551, -0.64223259, -0.9039365 ],
       [ 1.5800926 ,  0.3459128 ,  0.93263276, -1.54058094],
       [ 0.64699604, -0.44701417,  0.04640802, -1.28835763],
       [ 1.15767592,  0.72404547,  0.38619207,  1.81253003]])

names == 'Bob'
输出:array([ True, False, False,  True, False, False, False])

data[names == 'Bob']
输出:array([[-1.12065753,  1.46287992,  0.13695028, -1.89878434],
       [ 1.11837109, -0.61663551, -0.64223259, -0.9039365 ]])

data[names == 'Bob', 2:]
输出:array([[ 0.13695028, -1.89878434],
       [-0.64223259, -0.9039365 ]])

data[names == 'Bob', 0]
输出:array([-1.12065753,  1.11837109])

data[names != 'Bob'] #与&,或|, 非!=或者在布尔表达式前加-
输出:array([[ 0.64101753,  0.76381041,  0.04337704, -0.69203921],
       [-1.42369882, -0.2431481 , -0.87991876, -0.09632813],
       [ 1.5800926 ,  0.3459128 ,  0.93263276, -1.54058094],
       [ 0.64699604, -0.44701417,  0.04640802, -1.28835763],
       [ 1.15767592,  0.72404547,  0.38619207,  1.81253003]])

mask = (names == 'Bob') | (names == 'Will')
data[mask]
输出:array([[-1.12065753,  1.46287992,  0.13695028, -1.89878434],
       [-1.42369882, -0.2431481 , -0.87991876, -0.09632813],
       [ 1.11837109, -0.61663551, -0.64223259, -0.9039365 ],
       [ 1.5800926 ,  0.3459128 ,  0.93263276, -1.54058094]])

可以通过布尔型数组设置值:

data[data < 0] = 0
data
输出:array([[0.        , 1.46287992, 0.13695028, 0.        ],
       [0.64101753, 0.76381041, 0.04337704, 0.        ],
       [0.        , 0.        , 0.        , 0.        ],
       [1.11837109, 0.        , 0.        , 0.        ],
       [1.5800926 , 0.3459128 , 0.93263276, 0.        ],
       [0.64699604, 0.        , 0.04640802, 0.        ],
       [1.15767592, 0.72404547, 0.38619207, 1.81253003]])

data[names != 'Joe'] = 7
data
输出:array([[7.        , 7.        , 7.        , 7.        ],
       [0.64101753, 0.76381041, 0.04337704, 0.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [7.        , 7.        , 7.        , 7.        ],
       [0.64699604, 0.        , 0.04640802, 0.        ],
       [1.15767592, 0.72404547, 0.38619207, 1.81253003]])

3、花式索引

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.]])

arr[[4, 3, 0, 6]]
输出:array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])

arr[[-1, -3, -5]] #负数索引从后向前计数,从-1开始
输出:array([[7., 7., 7., 7.],
       [5., 5., 5., 5.],
       [3., 3., 3., 3.]])

arr = np.arange(32).reshape((8, 4))
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
输出:array([ 4, 23, 29, 10])

arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
输出:array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])] 
#np.ix_函数,可以将两个一维数组转化为一个选取方形区域的索引器
输出:array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])
上一篇下一篇

猜你喜欢

热点阅读