In the linked answer, How to set first N elements of array to zero?
the solution for arrays is
y = numpy.array(x)
y[0:n] = 0
In other words if we are filling a slice (range of indices) with the same number we can specify a scalar. It could be an array of the same size, e.g. np.ones(n)
. But it doesn't have to be.
So we just need to iterate over the rows of a
(and elements of b
) and perform this indexed assignment
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]])
There are various ways of 'filling' the original array with nan
. np.full
does an np.empty
followed by a copyto
.
A variation on the row iteration is with for i,n in enumerate(a):
.
Another good way of iterating in a coordinated sense is with zip
.
In [371]: for i,x in zip(b,a):
...: x[:i] = 1
This takes advantage of the fact that iteration on a 2d array iterates on its rows. So x
is an 1d view of a
and can be changed in-place.
But with a bit of indexing trickery, we don't even have to loop.
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]])
This is a favorite of one of the top numpy
posters, @Divakar
.
Numpy: Fix array with rows of different lengths by filling the empty elements with zeros
It can be used to pad
a list of lists. Speaking of padding, itertools
has a handy tool, zip_longest
(py3 name)
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]])
Your question should have specified what was wrong; what kinds of errors you got:
for i in w2:
a[0:b[i]] = [1] * b[i]
a[i:] = np.ones((b[i]))
w2
is unspecified, but probably is range(3)
.
a[0:b[i]]
is wrong because it specifies all rows, where as you are working on just one at a time. a[i:]
specifies a range of rows as well.