【问题标题】:How to manually select values from an array如何手动从数组中选择值
【发布时间】:2021-05-26 18:28:02
【问题描述】:

例如我有一个矩阵数组

a=np.arrange(25).shape(5,5)
[[ 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]]

如何制作一个我想手动选择的元素的一维数组?例如 [2,3]、[4,1]、[1,0] 和 [2,2],所以我得到以下内容:

b=[13, 21, 5, 12]

数组应该是引用而不是副本。

【问题讨论】:

  • 您是在问是否可以创建数组的不连续视图?
  • 是的,我研究过 Numpy 索引例程,但似乎没有一个函数提供这样的选项
  • 您也许可以为此编写自己的类,称为CustomView,作为a.view() 的一种包装器,尽管这显然比内置方法要慢。虽然拥有它似乎是一件好事,但我同意没有明显的内置解决方案(这并不意味着没有内置解决方案)。
  • b 的结果对于 2,3 和 4,1 肯定是错误的
  • @GoldenLion [4,1] 确实错了,谢谢

标签: python arrays numpy multidimensional-array


【解决方案1】:

你可以为此创建一个函数。

# defining the function
def get_value(matrix, row_list, col_list):
    for i, j in zip(row_list, col_list):
        return matrix[row_list, col_list]

# initializing the array
a = np.arange(0, 25, 1).reshape(5, 5)

# getting the required values and printing
b = get_value(a, [2,4,1,0], [3,1,0,2])

# output
print(b)

编辑

我会让之前的答案保持原样,以防万一其他人偶然发现它并需要它。

问题想要的是从b(即b[0],即13)中给出一个值,并根据来自b 的传递值的索引从原始矩阵a 中更改值在a

def change_the_value(old_mat, val_to_change, new_val):
    mat_coor = np.array(np.matrix(np.where(old_mat == val_to_change)).T)[0]
    old_mat[mat_coor[0], mat_coor[1]] = new_val
 
a = np.arange(0, 25, 1).reshape(5,5)
b = [13, 16, 5, 12]

change_the_value(a, b[0], 0)

【讨论】:

  • 该函数有效,但它返回一个新数组。对于我的情况,我需要能够更改初始数组,所以我需要一个视图,而不是副本。
  • 您想永久更改a 的值吗?你说的是这个吗?
  • 我需要能够通过 b 更改数组 a
  • 我认为我的措辞不正确。最初,a 是一个 5x5 矩阵,在执行任务后你希望a 成为array([13, 21, 5, 2])
  • 我希望a 保持不变,但如果我再做b[0]=0 那么a[2,3] 应该变为零
【解决方案2】:
a=np.arange(25).reshape(5,5)
search=[[2,3], [4,1], [1,0], [2,2]]
for row,col in search:
    print(row,col, a[row][col])

输出:

r c result
2 3 13
4 1 21
1 0 5
2 2 12

【讨论】:

  • 严格来说可行,但涉及列表,它不如 Numpy 数组快。不过,我现在使用的是相同的解决方案,但是使用了一个元组列表,因为它们有资格作为准备就绪的索引。我正在考虑一个更原生的 Numpy 解决方案。
【解决方案3】:

首先,我发现构建 Numpy 数组的非连续视图本身是不可能的,因为 Numpy 有效地利用了数组的连续内存布局,从而显着提高了速度。

这是我发现迄今为止效果最好的解决方案: 我没有查看数组,而是构造了一个集合索引,我想处理它,[2,3], [4,1], [1,0], [2,2]。 我选择的集合类型是 Sets,因为排除了重复项以及不需要搜索的 set().addset().discard 方法。没有必要维持秩序。

要使用它们来索引数组,必须将它们从一组元组 set{(2,3),(4,1),(1,0),(2,2)} 转换为一组数组元组 (ndarray([2,4,1,2], ndarray[3,1,0,2])

这可以通过解压缩一个集合并构造一个数组元组来实现:

import numpy as np
a=np.arrange(25).shape(5,5)
>>>[[ 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]]

my_set = {(2,3),(4,1),(1,0),(2,2)}
uzip_set = list(zip(*my_set))
seq_from_set = (np.asarray(uzip_set[0]),np.asarray(uzip_set[1]))
print(seq_from_set)
>>>(array[2,4,1,2], array[3,1,0,2])

而数组a可以通过提供这样一个索引序列来操作:

b = a[seq_from_set]
print(b)
>>>array[13,21,5,12]  
a[seq_from_set] = 0
print(a)   
 >>>[[ 0  1  2  3  4]
     [ 0  6  7  8  9]
     [10 11  0  0 14]
     [15 16 17 18 19]
     [20  0 22 23 24]]

与原生解决方案相比,该解决方案有点复杂,但运行速度惊人。这样可以轻松管理索引集合,并支持按需快速转换为索引流。

【讨论】:

    猜你喜欢
    • 2014-03-02
    • 1970-01-01
    • 2021-11-26
    • 2017-12-12
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    相关资源
    最近更新 更多