Efficient way to create a numpy boolean array from an array [duplicate] - python

This question already has answers here:
Construct two dimensional numpy array from indices and values of a one dimensional array
(3 answers)
Closed 4 years ago.
I am trying to convert a numpy array
np.array([1,3,2])
to
np.array([[1,0,0],[0,0,1],[0,1,0]])
Any idea of how to do this efficiently?
Thanks!

Create an bool array, and then fill it:
import numpy as np
a = np.array([1, 2, 3, 0, 3, 2, 1])
b = np.zeros((len(a), a.max() + 1), bool)
b[np.arange(len(a)), a] = 1

It is also possible to just select the right values from np.eye or the identity matrix:
a = np.array([1,3,2])
b = np.eye(max(a))[a-1]
This would probably be the most straight forward.

You can compare to [1, 2, 3] like so:
>>> a = np.array([1,3,2])
>>> np.equal.outer(a, np.arange(1, 4)).view(np.int8)
array([[1, 0, 0],
[0, 0, 1],
[0, 1, 0]], dtype=int8)
or equivalent but slightly faster
>>> (a[:, None] == np.arange(1, 4)).view(np.int8)

Try pandas's get dummy method.
import pandas as pd
import numpy as np
arr = np.array([1 ,3, 2])
df = pd.get_dummies(arr)
if what you need is numpy array object, do:
arr2 = df.values

Related

Replace occurences of a numpy array in another numpy array with a value

I have a 2D numpy array:
[[1,2,3,4,5],[2,4,5,6,7],[0,9,3,2,4]]
I also have a second 1D array:
[2,3,4]
I want to replace all occurences of the elements of the second array with 0
So eventually, my second array should look like
[[1,0,0,0,5],[0,0,5,6,7],[0,9,0,0,0]]
is there a way in python/numpy I can do this without using a loop.
I already checked at np.where, but the condition there is only for example where element = 1 value, and not multiple.
Thanks a lot !
Use numpy.isin.
>>> import numpy as np
>>> a = np.array([[1,2,3,4,5],[2,4,5,6,7],[0,9,3,2,4]])
>>> b = np.array([2,3,4])
>>> a[np.isin(a, b)] = 0
>>> a
array([[1, 0, 0, 0, 5],
[0, 0, 5, 6, 7],
[0, 9, 0, 0, 0]])

numpy: split 2d numpy array and then create 2d diagonal block array [duplicate]

This question already has answers here:
How can I transform blocks into a blockdiagonal matrix (NumPy)
(3 answers)
Closed 1 year ago.
Suppose, I got a 2D (n \times 2*n) numpy array like below,
dat = np.array([[1,2,3,4],[5,6,7,8]])
I want to split it into two 2d array equally, and then create a 2d diagonal block array, like below,
a = dat[:,0:2]
b = dat[:,2:]
result = np.block([
[a, np.zeros((2, 2))],
[np.zeros((2, 2)), b ]
])
Is there any better way in numpy that I dont need to specify this part "np.zero((n,n))"
Use scipy.linalg.block_diag
>>> import scipy.linalg
>>> scipy.linalg.block_diag(a, b)
array([[1, 2, 0, 0],
[5, 6, 0, 0],
[0, 0, 3, 4],
[0, 0, 7, 8]])
Taken from this post

Make 1 dimensional array 2D using numpy

I have a list of numbers which I wish to add a second column such that the array becomes 2D like in the example below:
a = [1,1,1,1,1]
b = [2,2,2,2,2]
should become:
c = [[1,2],[1,2],[1,2],[1,2],[1,2]]
I am not sure how to do this using numpy?
I would just stack them and then transpose the resulting array with .T:
import numpy as np
a = np.array([1, 1, 1, 1, 1])
b = np.array([2, 2, 2, 2, 2])
c = np.stack((a, b)).T
Use numpy built-in functions:
import numpy as np
c = np.vstack((np.array(a),np.array(b))).T.tolist()
np.vstack stacks arrays vertically. .T transposes the array and tolist() converts it back to a list.
Another similar way to do it, is to add a dimensions using [:,None] and then you can horizontally stack them without the need to transpose:
c = np.hstack((np.array(a)[:,None],np.array(b)[:,None])).tolist())
output:
[[1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]

Convert discontinuous numpy array to continuous array Python [duplicate]

This question already has answers here:
numpy replace groups of elements with integers incrementally
(2 answers)
Closed 4 years ago.
Hi I have a numpy array like
a = np.array([1,1,1,3,3,6,6,6,6,6,6])
I want to convert it to a continuous array like below
b = np.array([0,0,0,1,1,2,2,2,2,2,2])
I have a code for this using for loop
def fun1(a):
b = a.copy()
for i in range(1,a.shape[0]):
if a[i] != a[i-1]:
b[i] = b[i-1]+1
else:
b[i] = b[i-1]
b = b - b.min()
return b
Is there a way to vectorize this using numpy? I can use numba to make it faster but I was wondering if there is way to do it with just numpy.
You can do the following with np.unique, using the return_inverse argument. According to the docs:
return_inverse : bool, optional
If True, also return the indices of the unique array (for the specified axis, if provided) that can be used to reconstruct ar.
a = np.array([1,1,1,3,3,6,6,6,6,6,6])
_, b = np.unique(a, return_inverse=True)
>>> b
array([0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2])
Edit If the list starts out unsorted, and you want such a continuous array as displayed in your output, you can do the same as above, but passing a sorted array to np.unique:
a = np.array([1,3,1,3,3,6,6,3,6,6,6])
_, b = np.unique(sorted(a), return_inverse=True)
>>> b
array([0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2])

Iterate over numpy.ma array, ignoring masked values

I would like to iterate over only unmasked values in a np.ma.ndarray.
With the following:
import numpy as np
a = np.ma.array([1, 2, 3], mask = [0, 1, 0])
for i in a:
print i
I get:
1
--
3
I would like to get the following:
1
3
It seems like np.nditer() may be the way to go, but I don't find any flags that might specify this. How might I do this? Thanks!
you want to use a.compressed()
import numpy as np
a = np.ma.array([1, 2, 3], mask = [0, 1, 0])
for i in a.compressed():
print i
which gives:
1
3

Categories

Resources