0

I want to replace an item in a numpy array composed of 0 and 1. I want to replace 1 with the list [0,1] and the 0 with the list [1,0].

I found the function numpy.where(), but it doesn't work with lists. Is there a function or something similar to do the equivalent for numpy.where(vector==1,[0,1], [1,0]) ?

1
  • I get the feeling you're trying to create a one-hot tensor. Is that the purpose? Commented Jan 16, 2018 at 8:05

5 Answers 5

2

Simple indexing should do the job:

In [156]: x = np.array([0,1,0,0,1,1,0])
In [157]: y = np.array([[1,0],[0,1]])
In [158]: y[x]
Out[158]: 
array([[1, 0],
       [0, 1],
       [1, 0],
       [1, 0],
       [0, 1],
       [0, 1],
       [1, 0]])

And just to be sure this is a general solution, not some 'boolean' fluke

In [162]: x = np.array([0,1,0,0,1,2,2])
In [163]: y = np.array([[1,0],[0,1],[1,1]])
In [164]: y[x]
Out[164]: 
array([[1, 0],
       [0, 1],
       [1, 0],
       [1, 0],
       [0, 1],
       [1, 1],
       [1, 1]])
Sign up to request clarification or add additional context in comments.

1 Comment

This is the answer the OP is looking for, not the one s/he accepted. Anyway, very neat!
1

You can actually use where for that if you wish:

>>> import numpy as np
>>> vector = np.random.randint(0, 2, (8, 8))
>>> vector
array([[1, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 1, 0, 0, 0, 1],
       [1, 0, 0, 1, 1, 1, 0, 0],
       [1, 0, 1, 1, 0, 0, 0, 0],
       [0, 1, 0, 1, 1, 1, 1, 1],
       [1, 0, 1, 1, 0, 0, 0, 0],
       [0, 1, 1, 0, 1, 1, 0, 0],
       [1, 1, 1, 1, 1, 1, 0, 0]])
>>> np.where(vector[..., None] == 1, [0,1], [1,0])
# btw. if vector has only 0 and 1 entries you can leave out the " == 1 "
array([[[0, 1],
        [1, 0],
        [1, 0],
        [1, 0],
        [1, 0],
        [1, 0],
        [0, 1],
        [0, 1]],

       [[0, 1],
        [0, 1],
        [1, 0],
        [0, 1],
        [1, 0],
        [1, 0],
        [1, 0],

        etc.

Comments

0

Looks like you want to make one-hot vector encoding:

a = np.array([1, 0, 1, 1, 0])  # initial array
b = np.zeros((len(a), 2))  # where 2 is number of classes
b[np.arange(len(a)), a] = 1
print(b)

result:

array([[ 0.,  1.],
       [ 1.,  0.],
       [ 0.,  1.],
       [ 0.,  1.],
       [ 1.,  0.]])

2 Comments

It's a coincidence. I have a lot of elements in my array. Ist here a way to make it less "expensive"?
anyway you will need to create auxiliary array to store result because numpy does not allow dynamically change dimensions for specific items. So my solution must work for your problem (in case of 1-rank input array)
0

Since it's not possible to grow the array dynamically in NumPy, you've to convert the array to list, do the substitution as desired, and then convert the result back to NumPy array like:

In [21]: vector = np.array([0, 0, 1, 0, 1])

In [22]: vlist = vector.tolist()

In [23]: vlist
Out[23]: [0, 0, 1, 0, 1]

In [24]: new_list = [[1, 0] if el == 0 else [0, 1] for idx, el in enumerate(vlist)]

In [25]: result = np.array(new_list)

In [26]: result
Out[26]: 
array([[1, 0],
       [1, 0],
       [0, 1],
       [1, 0],
       [0, 1]])

If your 1D array is not that large enough, then list comprehension is not that bad of an approach.

Comments

0

hpaulj's answer would be the ideal way of doing this. An alternative is to reshape your original numpy array, and apply your standard np.where() operation.

import numpy as np

x = np.array([0,1,0,0,1,1,0])
x = np.reshape(x,(len(x),1))
# Equivalently, if you want to be explicit:
# x = np.array([[e] for e in x])
print np.where(x==1,[1,0],[0,1])
# Result:
array([[0, 1],
       [1, 0],
       [0, 1],
       [0, 1],
       [1, 0],
       [1, 0],
       [0, 1]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.