17.python(库)Numpy中:数组操作

1. 通用函数

在上一篇文章《Python常用库(六):科学计算库Numpy[上篇]:创建、访问、赋值》中学习了Numpy的创建、访问、赋值。接下来学习数组的其他函数,Numpy提供了一系列操作数组的函数,通常称这种函数为通用函数(ufunc); 可以直接作用在数组中的每个元素(无需遍历) 。

@注意: 通用函数(ufunc)是NumPy中的一个重要概念,而不是一个具体的库,ufuncuniversal function的缩写。

2. 元素查找

2.1 np.where

numpy.where 根据给定条件返回数组中满足条件元素,对应的索引。它的语法如下:

numpy.where(condition[, x, y])

a. 参数说明:

  • condition:一个布尔型数组或条件表达式,指定了要检查的条件。
  • x:可选参数,表示满足条件的元素替换为该值,默认为None
  • y:可选参数,表示不满足条件的元素替换为该值,默认为None

numpy.where 返回一个新的数组,其中满足条件的元素被替换为 x,不满足条件的元素被替换为 y。如果只传入 condition 参数,则返回满足条件的元素的索引。

b. 使用示例:

import numpy as np
if __name__ == '__main__':
    print("--------------------------- 在一维数组查询 ---------------------------")
    arr = np.random.randint(1, 12, 6)
    print("随机一维数组:", arr)
    # 在一维数组查询,返回满足条件元素对应的索引
    print("查询 >6,返回满足条件元素对应的索引: ", np.where(arr > 6))
    # 把满足条件的元素替换成:88,不满足替换成:-1
    replace_arr = np.where(arr > 6, 88, -1)
    print("把满足 arr>6 的元素,替换成:88,不满足替换成:-1 ", replace_arr)

    print("--------------------------- 在二维数组查询 ---------------------------")
    two_arr = np.random.randint(1, 12, (2, 3))
    print("随机二维数组:\n", two_arr)
    # 在二维数组查询
    print("查询>6,返回满足条件元素对应的索引: ", np.where(two_arr > 6))
    

"""
--------------------------- 在一维数组查询 ---------------------------
随机一维数组: [5 6 2 8 5 9]
查询 >6,返回满足条件元素对应的索引:  (array([3, 5], dtype=int64),)
把满足 arr>6 的元素,替换成:88,不满足替换成:-1  [-1 -1 -1 88 -1 88]
--------------------------- 在二维数组查询 ---------------------------
随机二维数组:
 [[9 3 1]
 [4 5 9]]
查询>6,返回满足条件元素对应的索引:  (array([0, 1], dtype=int64), array([0, 2], dtype=int64))
"""    

3. 逻辑判断

3.1 np.all

numpy.all() 函数用于检查数组中的所有元素是否满足给定条件。如果数组中的所有元素都满足条件,则返回 True,否则返回 False。语法如下:

numpy.all(condition, axis=None)

a. 参数说明:

  • condition:一个条件表达式,可以是比较运算、逻辑运算等。
  • axis 参数是可选的,用于指定沿着哪个轴进行计算.

b. 使用示例:

import numpy as np

if __name__ == '__main__':
    arr = np.arange(10)
    print("一维数组:", arr)
    print("arr所有元素 >6:", np.all(arr > 6))
    two_arr = np.array([
        [5, 19, 7],
        [7, 34, 8],
        [12, 14, 30],
    ])
    print("二维数组:\n", two_arr)
    print("two_arr数组所有元素 >4:", np.all(two_arr > 4))
    print("two_arr数组所有行(横轴)元素 >10:", np.all(two_arr > 10, axis=1))
    print("two_arr数组所有列(纵轴)元素 >10:", np.all(two_arr > 10, axis=0))
    
"""
一维数组: [0 1 2 3 4 5 6 7 8 9]
arr所有元素 >6: False
二维数组:
 [[ 5 19  7]
 [ 7 34  8]
 [12 14 30]]
two_arr数组所有元素 >4: True
two_arr数组所有行(横轴)元素 >10: [False False  True]
two_arr数组所有列(纵轴)元素 >10: [False  True False]
"""    

3.2 np.any

np.any函数用于判断数组中是否存在满足某个条件的元素。它返回一个布尔值,如果存在满足条件的元素,则返回True,否则返回False
np.any函数的语法如下:

numpy.any(a, axis=None, out=None, keepdims=<no value>, *, where=<no value>)

a. 参数说明:

  • axis:沿着指定的轴进行操作,默认为None,表示对整个数组进行操作。
  • out:指定输出结果的数组。
  • keepdims:如果设置为True,则保持原始数组的维度不变;如果设置为False,则将缩减的维度删除。
  • where:可选参数,用于指定额外的条件。

b. 使用示例:

import numpy as np

if __name__ == '__main__':
    arr = np.arange(10)
    print("一维数组:", arr)
    print("arr所有元素 >6:", np.any(arr > 6))
     two_arr = np.array([
        [5, 9, 7],
        [7, 8, 43],
        [12, 4, 13],
    ])
    print("二维数组:\n", two_arr)
    print("two_arr数组所有元素 >12:", np.any(two_arr > 12))
    print("two_arr数组所有行(横轴)元素 >40:", np.any(two_arr > 40, axis=1))
    print("two_arr数组所有列(纵轴)元素 >12:", np.any(two_arr > 12, axis=0))


"""
一维数组: [0 1 2 3 4 5 6 7 8 9]
arr所有元素 >6: True
二维数组:
 [[ 5  9  7]
 [ 7  8 43]
 [12  4 13]]
two_arr数组所有元素 >12: True
two_arr数组所有行(横轴)元素 >40: [False  True False]
two_arr数组所有列(纵轴)元素 >12: [False False  True]
"""    

4. 数组排序

4.1 sort

np.sort() 用于对数组进行排序。返回原始数组的已排序副本,并且不会改变原始数组的顺序。

sort(a, axis=-1, kind=None, order=None)

a. 参数说明:

  • axis: 表示沿着指定轴排序,默认值为 -1,表示沿着最后一个轴进行排序。
  • kind: 表示使用哪种算法进行排序,默认快速排序算法(quicksort),也可以选择其他算法(mergesort:归并排序、heapsort:堆排序)。
  • order: 当数组是结构化或复合类型时,可以指定排序的字段,默认None:表示按照数组中的元素正序排序

b. 使用示例:

import numpy as np

if __name__ == '__main__':
    print("------------------ 普通数组示例 ------------------")
    one_arr = np.array([4, 1, 3, 2])
    print("待排序一维数组:", one_arr)
    print("默认正序:", np.sort(one_arr))
    print("倒序:", np.sort(one_arr)[::-1])

    two_arr = np.array([
        [15, 11, 6],
        [7, 5, 1],
        [14, 21, 12],
    ])
    print("待排序-二维数组:\n", two_arr)
    print("二维数组-默认排序:\n", np.sort(two_arr))
    print("二维数组-axis=0:\n", np.sort(two_arr, axis=0))
    print("二维数组-axis=1:\n", np.sort(two_arr, axis=1))
    print("------------------ 结构数组示例 ------------------")
    # 定义结构化数组数据类型
    dt = np.dtype([("name", "U10"), ("age", int), ("score", float)])
    # 创建结构化数组
    arr = np.array([
        ("张三", 20, 68.5),
        ("李四", 22, 80),
        ("王麻子", 25, 95.5),
    ], dtype=dt)
    print("结构化数组: ", arr)
    sort_arr = np.sort(arr, order='age')
    print("结构化数组-根据age排序: ", arr)
    print("结构化数组-根据age倒序: ", arr[::-1])
    
"""
------------------ 普通数组示例 ------------------
待排序一维数组: [4 1 3 2]
默认正序: [1 2 3 4]
倒序: [4 3 2 1]
待排序-二维数组:
 [[15 11  6]
 [ 7  5  1]
 [14 21 12]]
二维数组-默认排序:
 [[ 6 11 15]
 [ 1  5  7]
 [12 14 21]]
二维数组-axis=0:
 [[ 7  5  1]
 [14 11  6]
 [15 21 12]]
二维数组-axis=1:
 [[ 6 11 15]
 [ 1  5  7]
 [12 14 21]]
------------------ 结构数组示例 ------------------
结构化数组:  [('张三', 20, 68.5) ('李四', 22, 80. ) ('王麻子', 25, 95.5)]
结构化数组-根据age排序:  [('张三', 20, 68.5) ('李四', 22, 80. ) ('王麻子', 25, 95.5)]
结构化数组-根据age倒序:  [('王麻子', 25, 95.5) ('李四', 22, 80. ) ('张三', 20, 68.5)]
"""    

5. 数组分割

5.1 np.array_split

np.array_split : 用于将一个数组分割成多个子数组。函数的语法如下:

numpy.array_split(arr, indices_or_sections, axis=0)

a.参数说明:

  • arr:要分割的数组。
  • indices_or_sections:指定分割点的位置。可以是一个整数,表示要分成几个等份;也可以是一个由分割点位置组成的列表,表示按照这些位置进行分割。
  • axis:指定在哪个轴上进行分割,行(0)、列(1) ;默认为 0,表示按行进行分割。

b.使用示例:

import numpy as np

if __name__ == '__main__':
    print("------------------------ 分割一维数组 ----------------------------------")
    # 创建一个一维数组
    one_arr = np.arange(11)
    print("原始一维数组: ", one_arr)
    # 将数组分割成两个子数组
    print("分割成2个子数组: ", np.array_split(one_arr, 2))
    print("分割成3个子数组: ", np.array_split(one_arr, 3))
    print("由分割点分割子数组: ", np.array_split(one_arr, [3, 6]))

    print("------------------------ 分割二维数组 ----------------------------------")
    # 创建一个二维数组
    two_arr = np.arange(6).reshape((2, 3))
    print("原始二维数组: \n", two_arr)
    # 按列分割数组
    result = np.array_split(two_arr, 3, axis=1)
    print("按列分割数组: \n", result)

    # 按行分割数组
    result = np.array_split(two_arr, 2, axis=0)
    print("按行分割数组: \n", result)
    
""" 
------------------------ 分割一维数组 ----------------------------------
原始一维数组:  [ 0  1  2  3  4  5  6  7  8  9 10]
分割成2个子数组:  [array([0, 1, 2, 3, 4, 5]), array([ 6,  7,  8,  9, 10])]
分割成3个子数组:  [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8,  9, 10])]
由分割点分割子数组:  [array([0, 1, 2]), array([3, 4, 5]), array([ 6,  7,  8,  9, 10])]
------------------------ 分割二维数组 ----------------------------------
原始二维数组: 
 [[0 1 2]
 [3 4 5]]
按列分割数组: 
 [array([[0],
       [3]]), array([[1],
       [4]]), array([[2],
       [5]])]
按行分割数组: 
 [array([[0, 1, 2]]), array([[3, 4, 5]])]
"""

5.2 np.dsplit

np.dsplit 函数可以将多维数组,以垂直方向(沿着行)进分割成多个子数组,函数签名如下:

numpy.dsplit(arr, indices_or_sections)

a. 参数说明:

  • ary:要分割的多维数组。
  • indices_or_sections:可以是整数或一组整数,用于指定分割的位置。如果是整数,表示将数组分成等长的子数组。如果是一组整数,表示具体的划分位置;如[1,3]:代表分割 [0,1)、[1、3)、[3、最后)

b. 使用示例:

import numpy as np

if __name__ == '__main__':
    # 创建一个二维数组
    two_arr = np.arange(12).reshape((1, 3, 4))
    print("原始三维数组: \n", two_arr)
    print("------------------------ 按照份数分割 ------------------------")
    res_arr = np.dsplit(two_arr, 4)
    print("切割结果res_arr:\n", res_arr)
    print("res_arr[0]:\n", res_arr[0])
    print("------------------------ 按照位置分割 ------------------------")
    a = np.dsplit(two_arr, [1, 3])
    print("a: \n", a)
    print("a[0]: \n", a[0])
    print("a[1]: \n", a[1])
    print("a[2]: \n", a[2])
    
"""
原始三维数组: 
 [[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]]
------------------------ 按照份数分割 ------------------------
切割结果res_arr:
 [array([[[0],
        [4],
        [8]]]), array([[[1],
        [5],
        [9]]]), array([[[ 2],
        [ 6],
        [10]]]), array([[[ 3],
        [ 7],
        [11]]])]
res_arr[0]:
 [[[0]
  [4]
  [8]]]
------------------------ 按照位置分割 ------------------------
a: 
 [array([[[0],
        [4],
        [8]]]), array([[[ 1,  2],
        [ 5,  6],
        [ 9, 10]]]), array([[[ 3],
        [ 7],
        [11]]])]
a[0]: 
 [[[0]
  [4]
  [8]]]
a[1]: 
 [[[ 1  2]
  [ 5  6]
  [ 9 10]]]
a[2]: 
 [[[ 3]
  [ 7]
  [11]]]
"""    

5.3 np.hsplit

np.hsplit 函数可以将多维数组,以水平方向(沿着列)进分割成多个子数组,函数签名如下:

numpy.hsplit(ary, indices_or_sections)

a. 参数说明:

  • ary:要分割的数组。
  • indices_or_sections:可以是整数或一组整数,用于指定分割的位置。如果是整数,表示将数组分成等长的子数组。如果是一组整数,表示具体的划分位置。

b.使用示例:

import numpy as np

if __name__ == '__main__':
    # 创建一个二维数组
    arr = np.arange(12).reshape((1, 4, 3))
    print("原始三维数组: \n", arr)
    print("------------------------ 按照份数分割 ------------------------")
    res_arr = np.hsplit(arr, 4)
    print("切割结果res_arr:\n", res_arr)
    print("res_arr[0]:\n", res_arr[0])
    print("------------------------ 按照位置分割 ------------------------")
    # 第1行~第2行、第2行~第3行、第3行到最后
    a = np.hsplit(arr, [1, 2])
    print("a: \n", a)
    print("a[0]: \n", a[0])
    print("a[1]: \n", a[1])
    print("a[2]: \n", a[2])
    
"""
原始三维数组: 
 [[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]]
------------------------ 按照份数分割 ------------------------
切割结果res_arr:
 [array([[[0, 1, 2]]]), array([[[3, 4, 5]]]), array([[[6, 7, 8]]]), array([[[ 9, 10, 11]]])]
res_arr[0]:
 [[[0 1 2]]]
------------------------ 按照位置分割 ------------------------
a: 
 [array([[[0, 1, 2]]]), array([[[3, 4, 5]]]), array([[[ 6,  7,  8],
        [ 9, 10, 11]]])]
a[0]: 
 [[[0 1 2]]]
a[1]: 
 [[[3 4 5]]]
a[2]: 
 [[[ 6  7  8]
  [ 9 10 11]]]
"""    

6. 数组拼接

6.1 np.dstack

np.dstack 函数可以将多个数组,按照列拼接成更高一维度的数组
b. 使用示例:

import numpy as np

if __name__ == '__main__':
    print("--------------------------- 拼接一维 ---------------------------")
    # 定义一维数组
    arr1 = np.array([1, 2, 3])
    arr2 = np.array([4, 5, 6])
    arr3 = np.array([7, 8, 9])
    # 拼接
    arr = np.dstack((arr1, arr2, arr3))
    print("拼接一维数组结果: \n", arr)
    # 定义元组
    tuple1 = (1, 1, 1)
    tuple2 = (2, 2, 2)
    arr = np.dstack((tuple1, tuple2))
    print("拼接元组结果: \n", arr)
    print("--------------------------- 拼接二维 ---------------------------")
    two1 = two2 = np.array([
        [1, 2, 3],
        [4, 5, 6]
    ])
    print("拼接二维结果:\n", np.dstack((two1, two2)))
    
"""
--------------------------- 拼接一维 ---------------------------
拼接一维数组结果: 
 [[[1 4 7]
  [2 5 8]
  [3 6 9]]]
拼接元组结果: 
 [[[1 2]
  [1 2]
  [1 2]]]
--------------------------- 拼接二维 ---------------------------
拼接二维结果:
 [[[1 1]
  [2 2]
  [3 3]]

 [[4 4]
  [5 5]
  [6 6]]]
"""

6.2 np.hstack

np.hstack 函数用于在水平方向(按列)堆叠数组,也就是将多个数组按列连接起来。

import numpy as np

if __name__ == '__main__':
    print("--------------------------- 拼接一维 ---------------------------")
    # 定义一维数组
    arr1 = np.array([1, 2, 3])
    arr2 = np.array([4, 5, 6])
    arr3 = np.array([7, 8, 9])
    # 拼接
    arr = np.hstack((arr1, arr2, arr3))
    print("拼接一维数组结果: \n", arr)
    # 定义元组
    tuple1 = (1, 1, 1)
    tuple2 = (2, 2, 2)
    arr = np.hstack((tuple1, tuple2))
    print("拼接元组结果: \n", arr)
    print("--------------------------- 拼接二维 ---------------------------")
    two1 = two2 = np.array([
        [1, 2, 3],
        [4, 5, 6]
    ])
    print("拼接二维结果:\n", np.hstack((two1, two2)))
    
"""
--------------------------- 拼接一维 ---------------------------
拼接一维数组结果: 
 [1 2 3 4 5 6 7 8 9]
拼接元组结果: 
 [1 1 1 2 2 2]
--------------------------- 拼接二维 ---------------------------
拼接二维结果:
 [[1 2 3 1 2 3]
 [4 5 6 4 5 6]]
"""      

7. 维度转换

7.1 一维转多维

  • np.atleast_2d: 用于将输入的数组转成二维数组,如果输入数组是二维,则输出不变;
  • np.atleast_3d: 用于将输入的数组转成三维数组,如果输入数组是三维,则输出不变;
import numpy as np

if __name__ == '__main__':
    arr = np.array([1, 2, 3, 4])
    two_arr = np.arange(6).reshape((2, 3))
    # 转成二维
    print("---------------------- 转成二维 --------------------------")
    tmp = np.atleast_2d(arr)
    two_tmp = np.atleast_2d(two_arr)
    print("一维转二维:{} 维度:{}".format(tmp, tmp.ndim))
    print("二维转二维: \n {} \n维度:{}".format(two_tmp, two_tmp.ndim))
    # 转成三维
    print("---------------------- 转成三维 --------------------------")

    three_arr = np.atleast_3d(arr)
    three_arr2 = np.atleast_3d(two_arr)
    print("一维转三维:\n{} \n维度:{}".format(three_arr, three_arr.ndim))
    print("二维转三维:\n{} \n维度:{}".format(three_arr2, three_arr2.ndim))
    
"""
---------------------- 转成二维 --------------------------
一维转二维:[[1 2 3 4]] 维度:2
二维转二维: 
 [[0 1 2]
 [3 4 5]] 
维度:2
---------------------- 转成三维 --------------------------
一维转三维:
[[[1]
  [2]
  [3]
  [4]]] 
维度:3
二维转三维:
[[[0]
  [1]
  [2]]

 [[3]
  [4]
  [5]]] 
维度:3
"""    

7.2 多维转一维

NumPy中,你可以使用flatten()方法或ravel()方法来将二维或多维数组转换为一维数组。这两种方法的主要区别如下:

  • flatten() 方法返回的是原始数组的副本,因此对返回的数组的修改不会影响原始数组。
  • ravel() 方法返回的是原始数组的视图(引用),如果对返回的数组进行修改,可能会影响原始数组。
import numpy as np

if __name__ == '__main__':
    two_arr = np.arange(6).reshape((2, 3))
    three_arr = np.arange(8).reshape((2, 2, 2))
    print("原始二维数组:\n {}  \n原始三维数组:\n {} ".format(two_arr, three_arr))
    # 二维转一维
    print("二维转一维:", two_arr.flatten())

    # 三维转一维
    print("三维转一维:", three_arr.flatten())
    
"""
原始二维数组:
 [[0 1 2]
 [3 4 5]]  
原始三维数组:
 [[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]] 
二维转一维: [0 1 2 3 4 5]
三维转一维: [0 1 2 3 4 5 6 7]
"""    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容