如何替换数组中每个x的第一个f(x)值(x,n)

时间:2017-08-11 14:04:16

标签: python arrays numpy indexing iteration

我想将数组a的每一行中的前x个值替换为1,并保留所有其他值NaN。然而,前几个x值在每一行中都会发生变化,并由列表b确定。

由于我不熟悉数组,我认为我可以使用for循环执行此操作,如下所示,但这不起作用 (我从How to set first N elements of array to zero?)得到了阵列替换基础知识的灵感。

In:
a = np.empty((3,4))
a.fill(np.nan)
b = [2,3,1]

for i in range(b):
    a[0:b[i]] = [1] * b[i] 
    a[i:] = np.ones((b[i]))
pass

Out:
line 7:
ValueError: could not broadcast input array from shape (2) into shape (2,4)

结果应该是:

Out:
[[1, 1, nan, nan], 
 [1, 1, 1, nan], 
 [1, nan, nan, nan]] 

2 个答案:

答案 0 :(得分:2)

您可以通过循环执行此操作。初始化一个nan值数组,然后遍历前n个列表,并根据每行的n将值设置为1.

a = np.full((3, 4), np.nan)
b = [2, 3, 1]
for i, x in enumerate(b):
    a[i, :x] = 1

答案 1 :(得分:2)

在链接的答案How to set first N elements of array to zero?

数组的解决方案是

y = numpy.array(x)
y[0:n] = 0

换句话说,如果我们用相同的数字填充切片(索引范围),我们可以指定标量。它可以是相同大小的数组,例如np.ones(n)。但它不一定是。

所以我们只需要遍历a行(以及b的元素)并执行此索引作业

In [368]: a = np.ones((3,4))*np.nan
In [369]: for i in range(3):
     ...:     a[i,:b[i]] = 1
     ...:     
In [370]: a
Out[370]: 
array([[  1.,   1.,  nan,  nan],
       [  1.,   1.,   1.,  nan],
       [  1.,  nan,  nan,  nan]])

使用nan“填充”原始数组有多种方法。 np.full后跟np.empty copyto

行迭代的变体是for i,n in enumerate(a):

以协调的方式迭代的另一个好方法是使用zip

In [371]: for i,x in zip(b,a):
     ...:     x[:i] = 1

这利用了2d数组上的迭代迭代其行的事实。因此xa的1d视图,可以就地更改。

但是通过一些索引技巧,我们甚至不必循环。

In [373]: a = np.full((3,4),np.nan)

In [375]: mask = np.array(b)[:,None]>np.arange(4)
In [376]: mask
Out[376]: 
array([[ True,  True, False, False],
       [ True,  True,  True, False],
       [ True, False, False, False]], dtype=bool)
In [377]: a[mask] = 1
In [378]: a
Out[378]: 
array([[  1.,   1.,  nan,  nan],
       [  1.,   1.,   1.,  nan],
       [  1.,  nan,  nan,  nan]])

这是其中一张热门numpy海报的最爱,@Divakar

Numpy: Fix array with rows of different lengths by filling the empty elements with zeros

它可用于pad列表列表。说到填充,itertools有一个方便的工具,zip_longest(py3名称)

In [380]: np.array(list(itertools.zip_longest(*[np.ones(x).tolist() for x in b],fillvalue=np.nan))).T
Out[380]: 
array([[  1.,   1.,  nan],
       [  1.,   1.,   1.],
       [  1.,  nan,  nan]])

你的问题应该说清楚了什么;你得到了什么样的错误:

for i in w2:
    a[0:b[i]] = [1] * b[i] 
    a[i:] = np.ones((b[i]))

w2未指定,但可能是range(3)

a[0:b[i]]是错误的,因为它指定了所有行,而您一次只处理一行。 a[i:]也指定了一系列行。