Numpy 高级操作

In [1]:
import numpy as np
In [2]:
np.__version__
Out[2]:
'1.22.4'

获取满足条件的索引

In [3]:
arr_rand = np.array([8, 8, 3, 7, 7, 0, 4, 2, 5, 2])

查找数组中值大于 4 的元素的索引。

In [4]:
idx_gt4 = np.where(arr_rand > 4)
idx_gt4
Out[4]:
(array([0, 1, 3, 4, 8]),)

根据索引获取符合条件的数组元素。

In [5]:
arr_rand.take(idx_gt4)
Out[5]:
array([[8, 8, 7, 7, 5]])

获取数组中最大值和最小值的索引及值。

In [6]:
print(f"最小值索引:{np.argmin(arr_rand)}, 最小值:{np.min(arr_rand)}")
print(f"最大值索引:{np.argmax(arr_rand)}, 最大值:{np.max(arr_rand)}")
最小值索引:5, 最小值:0
最大值索引:0, 最大值:8

导入和导出 CSV 文件

In [7]:
# 关闭数字的科学表示法
np.set_printoptions(suppress=True)
In [8]:
path = "https://raw.githubusercontent.com/selva86/datasets/master/Auto.csv"

导入数据的标准方法是使用 np.genfromtxt 函数,它可以从 web URLs 导入数据,处理缺失值,支持多种分隔符,以及处理不规则的列数等功能。

In [9]:
data = np.genfromtxt(path, delimiter=",", skip_header=1, filling_values=-999)
In [10]:
data.shape
Out[10]:
(392, 9)
In [11]:
data[:3]
Out[11]:
array([[  18. ,    8. ,  307. ,  130. , 3504. ,   12. ,   70. ,    1. ,
        -999. ],
       [  15. ,    8. ,  350. ,  165. , 3693. ,   11.5,   70. ,    1. ,
        -999. ],
       [  18. ,    8. ,  318. ,  150. , 3436. ,   11. ,   70. ,    1. ,
        -999. ]])

最后,np.savetxt 将数据保存为 CSV 文件。

In [12]:
np.savetxt("out.csv", data, delimiter=",")

保存和加载 Numpy 数据

Numpy 提供了 .npy.npz 两种文件格式来存储数据。若要保存单个 ndarray 数据,可以使用 np.save 函数保存为 .npy 文件;若要保存多个 ndarray 数据,则可以使用 np.savez 函数保存为 .npz 文件。加载 numpy 数据时,统一使用 np.load 函数。

In [13]:
np.save("arr_rand.npy", arr_rand)
In [14]:
a = np.load("arr_rand.npy")
a
Out[14]:
array([8, 8, 3, 7, 7, 0, 4, 2, 5, 2])
In [15]:
np.savez("arr.npz", arr_rand, data)
In [16]:
b = np.load("arr.npz")
b.files
Out[16]:
['arr_0', 'arr_1']
In [17]:
b["arr_1"][:3]
Out[17]:
array([[  18. ,    8. ,  307. ,  130. , 3504. ,   12. ,   70. ,    1. ,
        -999. ],
       [  15. ,    8. ,  350. ,  165. , 3693. ,   11.5,   70. ,    1. ,
        -999. ],
       [  18. ,    8. ,  318. ,  150. , 3436. ,   11. ,   70. ,    1. ,
        -999. ]])

按行或按列拼接 Numpy 数组

In [18]:
a = np.zeros([2, 3], dtype=np.int32)
a
Out[18]:
array([[0, 0, 0],
       [0, 0, 0]], dtype=int32)
In [19]:
b = np.ones([2, 3], dtype=np.int32)
b
Out[19]:
array([[1, 1, 1],
       [1, 1, 1]], dtype=int32)

按行拼接,将多个数组在垂直方向上 (即行的方向) 合并成一个新的数组。

In [20]:
np.vstack([a, b])
Out[20]:
array([[0, 0, 0],
       [0, 0, 0],
       [1, 1, 1],
       [1, 1, 1]], dtype=int32)
In [21]:
np.concatenate([a, b], axis=0)
Out[21]:
array([[0, 0, 0],
       [0, 0, 0],
       [1, 1, 1],
       [1, 1, 1]], dtype=int32)

按列拼接,将多个数组在水平方向上 (列的方向) 进行连接。

In [22]:
np.hstack([a, b])
Out[22]:
array([[0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1]], dtype=int32)
In [23]:
np.concatenate([a, b], axis=1)
Out[23]:
array([[0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1, 1]], dtype=int32)

按列对数据进行排序

In [24]:
arr = np.random.randint(1, 6, size=[4, 3])
arr
Out[24]:
array([[4, 4, 3],
       [1, 2, 4],
       [2, 5, 3],
       [2, 5, 1]])

np.sort 排序函数认为所有列是相互独立的,对所有列进行排序,破坏了每行的结构。使用 np.argsort 函数对第一列进行排序,返回索引,再根据第一列的索引对数组排序,保留了行的完整性。

In [25]:
sorted_index_1 = arr[:, 0].argsort()
arr[sorted_index_1]
Out[25]:
array([[1, 2, 4],
       [2, 5, 3],
       [2, 5, 1],
       [4, 4, 3]])
In [26]:
arr[sorted_index_1[::-1]]  # 降序倒排
Out[26]:
array([[4, 4, 3],
       [2, 5, 1],
       [2, 5, 3],
       [1, 2, 4]])

若要基于多个列对数组进行排序,可以使用 np.lexsort 函数,其参数为元组类型,元组中的每个元素代表数组的某一列。排序规则是:越靠右的列,优先级越高。

In [27]:
sorted_index_1_and_2 = np.lexsort((arr[:, 1], arr[:, 0]))
arr[sorted_index_1_and_2]
Out[27]:
array([[1, 2, 4],
       [2, 5, 3],
       [2, 5, 1],
       [4, 4, 3]])

高阶函数

In [28]:
x = np.arange(5)
In [29]:
x_col = np.expand_dims(x, axis=-1)
x_col
Out[29]:
array([[0],
       [1],
       [2],
       [3],
       [4]])
In [30]:
x_col.shape
Out[30]:
(5, 1)
In [31]:
x_row = np.expand_dims(x, axis=0)
x_row
Out[31]:
array([[0, 1, 2, 3, 4]])
In [32]:
x_row.shape
Out[32]:
(1, 5)
In [33]:
# 按列操作,查找每列的最大值
np.apply_along_axis(np.max, 0, arr=arr)
Out[33]:
array([4, 5, 4])
In [34]:
# 按行操作,查找每行的最大值
np.apply_along_axis(np.max, 1, arr=arr)
Out[34]:
array([4, 4, 5, 5])

相关推荐