2017-05-29 114 views
1

我有指数列表的某些指标喜欢这样的:填写一个3D numpy的阵列

selected_coords = [[1, 8, 30], [15, 4, 6] ,...] 

而且这样的值的列表:

differences = [1, 5, 8, 2, ...] 

两者有500个条目。现在我想用这些值在正确的索引上填充一个3d numpy数组。我试图做的是:

brain_map = np.zeros(shape=(48,60,22)) 

for i, index in enumerate(selected_coords): 
    ind = list(map(int, index)) 
    brain_map[ind] = differences[i] 

如果我打印索引并在这个循环中我得到正确格式的价值,但如果我在循环之后打印矩阵好像值已被提在那里多次而不是只在指定的指数上。我究竟做错了什么?

+0

我在第一个索引中写了30个例子,我知道这是超出范围。实际数据中并非如此。 – maxmijn

回答

4

你应该尽可能避免在numpy数组上循环,否则你会失去性能。您可以使用advanced ("fancy") indexing来索引特定索引处的元素子集。这工作就像这样:

brain_map[ind_x,ind_y,ind_z] = vals 

其中ind_x, ind_y, ind_zvals是相同长度的所有一维数组喜欢。你有什么本质上是你的索引数组的转置:

brain_map[tuple(zip(*selected_coords))] = differences 

zip(*)伎俩基本上调换你的清单,然后可以为索引的元组传递的名单。例如:

>>> import numpy as np 
>>> M = np.random.rand(2,3,4) 
>>> coords = [[0,1,2],[1,2,3]] 
>>> tuple(zip(*coords)) 
((0, 1), (1, 2), (2, 3)) 
>>> M[tuple(zip(*coords))] 
array([ 0.12299864, 0.76461622]) 
>>> M[0,1,2],M[1,2,3] 
(0.12299863762892316, 0.76461622348724623) 
+0

非常感谢!所以基本上,除了数组循环的不良做法之外,代码不起作用,因为我没有使用元组进行索引? – maxmijn

+0

@maxmijn高级索引在一般情况下可能会非常复杂。对你的问题的简短回答是“是”:由于python的隐含性,基本(即非花哨)索引方案'M [i,j,k]'实际上代表'M [(i,j,k)]'元组语法。如果您使用元组以外的其他元素(通常是列表或数组)作为索引,则可能会触发花哨索引。所以'M [[i,j,k]]'给你一个包含'M [i]','M [j]'和'M [k]'的数组,每个隐式地对应于M [i ,: ,:]','M [j,:,:]','M [k,:,:]'。例如,比较'M [0,1,0]'和'M [[0,1,0]]''。后者是一个3d阵列。 –