How to efficiently unroll a matrix by value with numpy?

2024/10/9 22:18:26

I have a matrix M with values 0 through N within it. I'd like to unroll this matrix to create a new matrix A where each submatrix A[i, :, :] represents whether or not M == i.

The solution below uses a loop.

# Example Setup
import numpy as npnp.random.seed(0)
N = 5
M = np.random.randint(0, N, size=(5,5))# Solution with Loop
A = np.zeros((N, M.shape[0], M.shape[1]))
for i in range(N):A[i, :, :] = M == i

This yields:

M
array([[4, 0, 3, 3, 3],[1, 3, 2, 4, 0],[0, 4, 2, 1, 0],[1, 1, 0, 1, 4],[3, 0, 3, 0, 2]])M.shape
# (5, 5)A 
array([[[0, 1, 0, 0, 0],[0, 0, 0, 0, 1],[1, 0, 0, 0, 1],[0, 0, 1, 0, 0],[0, 1, 0, 1, 0]],...[[1, 0, 0, 0, 0],[0, 0, 0, 1, 0],[0, 1, 0, 0, 0],[0, 0, 0, 0, 1],[0, 0, 0, 0, 0]]])A.shape
# (5, 5, 5)

Is there a faster way, or a way to do it in a single numpy operation?

Answer

Broadcasted comparison is your friend:

B = (M[None, :] == np.arange(N)[:, None, None]).view(np.int8)np.array_equal(A, B)
# True

The idea is to expand the dimensions in such a way that the comparison can be broadcasted in the manner desired.


As pointed out by @Alex Riley in the comments, you can use np.equal.outer to avoid having to do the indexing stuff yourself,

B = np.equal.outer(np.arange(N), M).view(np.int8)np.array_equal(A, B)
# True
https://en.xdnf.cn/q/69971.html

Related Q&A

Anaconda Python 3.6 -- pythonw and python supposed to be equivalent?

According to Python 3 documentation, python and pythonw should be equivalent for running GUI scripts as of 3.6With older versions of Python, there is one Mac OS X quirk that you need to be aware of: pr…

Good way of handling NoneType objects when printing in Python

How do I go about printin a NoneType object in Python?# score can be a NonType object logging.info("NEW_SCORE : "+score)Also why is that sometime I see a comma instead of the + above?

problems with easy_install pycrypto

Im trying install pycrypto on osx with easy_install and Im getting the following error:easy_install pycrypto Searching for pycrypto Reading http://pypi.python.org/simple/pycrypto/ Reading http://pycryp…

What is the most efficient way to do a sorted reduce in PySpark?

I am analyzing on-time performance records of US domestic flights from 2015. I need to group by tail number, and store a date sorted list of all the flights for each tail number in a database, to be re…

Interactive figure with OO Matplotlib

Using Matplotlib via the OO API is easy enough for a non-interactive backend:from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasfrom matplotlib.figure import Figurefig = Figure(…

nose2 vs py.test with isolated processes

We have been using nosetest for running and collecting our unittests (which are all written as python unittests which we like). Things we like about nose:uses standard python unit tests (we like the st…

ValueError: Attempt to reuse RNNCell with a different variable scope than its first use

The following code fragmentimport tensorflow as tf from tensorflow.contrib import rnnhidden_size = 100 batch_size = 100 num_steps = 100 num_layers = 100 is_training = True keep_prob = 0.4input_da…

Convex Hull and SciPy

Im trying to use scipy (0.10.1) for a quick hack to visualize the convex hull.I can get the convex hull using the following code:vecs = [[-0.094218, 51.478927], [-0.09348, 51.479364], [-0.094218, 51.4…

Flask Confirm Action

Im creating a site using the Flask framework, and am implementing a confirmation page for (mainly administrative) actions; i.e. deleting a user.My current method (detailed below) works, but feels quite…

Regex for accent insensitive replacement in python

In Python 3, Id like to be able to use re.sub() in an "accent-insensitive" way, as we can do with the re.I flag for case-insensitive substitution.Could be something like a re.IGNOREACCENTS fl…