简体   繁体   English

如何使用字典键和值初始化 numpy 数组的位置?

[英]How to initialize locations of numpy array using dictionary keys and values?

I have the following numpy array which is basically a 3 channel image:我有以下 numpy 数组,它基本上是一个 3 通道图像:

arr = np.zeros((6, 4, 3), dtype=np.float32)

# dictionary of values, key is array location
values_of_channel_0 = {
        (0, 2) : 1,  
        (1, 0) : 1,  
        (1, 3) : 5,  
        (2, 1) : 2,  
        (2, 2) : 3,  
        (2, 3) : 1,  
        (3, 0) : 1,  
        (3, 2) : 2,  
        (4, 0) : 2,  
        (4, 2) : 20,  
        (5, 0) : 1,  
        (5, 2) : 10, 
        (5, 3) : 1 
}

I am trying to find the most elegant way to set all the values of the 3rd channel according to the dictionary.我正在尝试根据字典找到最优雅的方式来设置第三通道的所有值。 Here is what I tried:这是我尝试过的:

locations = list(values_of_channel_0.keys())
values = list(values_of_channel_0.values())
arr[lc,0] = values # trying to set the 3rd channel

But this fails.但这失败了。

Is there a way in which this can be done without looping over keys and values?有没有一种方法可以在不循环键和值的情况下完成?

What's wrong with a simple loop?一个简单的循环有什么问题? Something will have to iterate over the key/value-pairs you provide in your dictionary in any case?在任何情况下都必须迭代您在字典中提供的键/值对?

import numpy as np

arr = np.zeros((6, 4, 3), dtype=np.float32)

# dictionary of values, key is array location
values_of_channel_0 = {
        (0, 2) : 1,
        (1, 0) : 1,
        (1, 3) : 5,
        (2, 1) : 2,
        (2, 2) : 3,
        (2, 3) : 1,
        (3, 0) : 1,
        (3, 2) : 2,
        (4, 0) : 2,
        (4, 2) : 20,
        (5, 0) : 1,
        (5, 2) : 10,
        (5, 3) : 1
}

for (a, b), v in values_of_channel_0.items():
    arr[a, b, 0] = v

print(arr)

Result:结果:

[[[ 0.  0.  0.]
  [ 0.  0.  0.]
  [ 1.  0.  0.]
  [ 0.  0.  0.]]

 [[ 1.  0.  0.]
  [ 0.  0.  0.]
  [ 0.  0.  0.]
  [ 5.  0.  0.]]

 [[ 0.  0.  0.]
  [ 2.  0.  0.]
  [ 3.  0.  0.]
  [ 1.  0.  0.]]

 [[ 1.  0.  0.]
  [ 0.  0.  0.]
  [ 2.  0.  0.]
  [ 0.  0.  0.]]

 [[ 2.  0.  0.]
  [ 0.  0.  0.]
  [20.  0.  0.]
  [ 0.  0.  0.]]

 [[ 1.  0.  0.]
  [ 0.  0.  0.]
  [10.  0.  0.]
  [ 1.  0.  0.]]]

If you insist on not looping for the assignment, you can construct a data structure that can be assigned at once:如果坚持不循环赋值,可以构造一个可以一次性赋值的数据结构:

channel_0 = [[values_of_channel_0[b, a] if (b, a) in values_of_channel_0 else 0 for a in range(4)] for b in range(6)]

arr[..., 0] = channel_0

But this is clearly rather pointless and not even more efficient.但这显然毫无意义,甚至效率更高。 If you have some control over how values_of_channel_0 is constructed, you could consider constructing it as a nested list or array of the right dimensions immediately, to allow for this type of assignment.如果您对values_of_channel_0的构建方式有一定的控制权,您可以考虑立即将其构建为正确维度的嵌套列表或数组,以允许此类分配。

Users @mechanicpig and @michaelszczesny offer a very clean alternative (which will be more efficient since it relies on the efficient implementation of zip() ):用户@mechanicpig 和@michaelszczesny 提供了一个非常干净的替代方案(由于它依赖于zip()的高效实现,因此效率更高):

arr[(*zip(*values_of_channel_0), 0)] = list(values_of_channel_0.values())

Edit: you asked for an explanation of the lefthand side.编辑:您要求对左侧进行解释。

This hinges on the unpacking operator * .这取决于拆包运算符* *values_of_channel_0 spreads all the keys of the dictionary values_of_channel_0 into a call to zip() . *values_of_channel_0将字典values_of_channel_0的所有键传播到对zip()的调用中。 Since these keys are all 2- tuple s of int , zip will yield two tuples, one with all the first coordinates (0, 1, 1, ...) and the second with the second coordinates (2, 0, 3, ...) .由于这些键都是int的双tuple组,因此 zip 将产生两个元组,一个具有所有第一个坐标(0, 1, 1, ...) ,第二个具有第二个坐标(2, 0, 3, ...)

Since the call to zip() is also preceded by * , these two values will be spread to index arr[] , together with a final coordinate 0 .由于对zip()的调用也以*开头,这两个值将与最终坐标0一起扩展到索引arr[] So this:所以这:

arr[(*zip(*values_of_channel_0), 0)] = ...

Is essentially the same as:本质上是一样的:

arr[((0, 1, 1, ...), (2, 0, 3, ...), 0)] = ...

That's a slice of arr with exactly the same number of elements as the dictionary, including all the elements with the needed coordinates.这是arr的一部分,其元素数量与字典完全相同,包括具有所需坐标的所有元素。 And so assigning list(values_of_channel_0.values()) to it works and has the desired effect of assigning the matching values to the correct coordinates.因此,将list(values_of_channel_0.values())分配给它会起作用,并且具有将匹配值分配给正确坐标的预期效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将日期时间对象作为键并将numpy数组作为值的字典转换为2D numpy数组? - How to convert a dictionary with datetime objects as keys and numpy arrays as values to 2D numpy array? 如何自动提取与键关联的numpy数组表示的值作为字典中的单独数据 - How to automate extraction of values represented by numpy array associated with keys as separate data from a dictionary 如何用字典的值制作一个numpy数组? - How to make a numpy array with a dictionary's values? 我可以从字典键数组创建字典值的 numpy 数组吗? - Can I create a numpy array of dictionary values from an array of dictionary keys? 如何创建一个字典,其键为 integer 并定义为 numpy 数组? - How to create a dictionary with keys as integer and definition as a numpy array? 如何将 numpy 数组中的每一行分配到字典 python 中的键中 - How to assign each row in a numpy array into keys in dictionary python 如何使用顺序键将Numpy数组转换为Python字典? - How to convert Numpy Array to Python Dictionary with Sequential Keys? Python / numpy:获取值列表的数组位置 - Python/numpy: Get array locations of a list of values 如何使用字典将numpy中的NaN映射到值? - How to map NaN in numpy to values using dictionary? 如何使用每个条带的不同值初始化 numpy 二维数组 - How to initialize numpy 2D array with different values for each strip
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM