user2770149 user2770149 - 1 month ago 14
Python Question

logical arrays and mapping in python

I'm trying to vectorize some element calculations but having difficulty doing so without creating list comprehensions for local information to global information. I was told that I can accomplish what I want to do using logical arrays, but so far the examples I've found has not been helpful. While yes I can accomplish this with list comprehensions, speed is a main concern with my code.

I have a set of values that indicate indices in the "global" calculation that should not be adjusted.

For example, these "fixed" indices are

1 2 6


If my global calculation has ten elements, I would be able to set all the "free" values by creating a list of the set of the global indices and subtracting the fixed indices.

free = list(set(range(len(global)) - set(fixed))
[0, 3, 4, 5, 7, 8, 9]


in the global calculation, I would be able to adjust the "free" elements as shown in the following code snippet

global = np.ones(10)
global[free] = global[free] * 10


which should produce:

global = [10, 1, 1, 10, 10, 10, 1, 10, 10, 10]


my "local" calculation is a subset of the global one, where the local map indicates the corresponding indices in the global calculation.

local_map = [4, 2, 1, 8, 6]
local_values = [40, 40, 40, 40, 40]


but I need the values associated with the local map to retain their order for calculation purposes.

What would the equivalent of global[free] be on the local level?
the desired output would be something like this:

local_free = list(set(range(len(local)) - set(fixed))
local_values[local_free] *= 10
OUTPUT: local_values = [400, 40, 40, 400, 40]


I apologize if the question formatting is off, the code block formatting doesn't seem to be working in my browser, so please let me know if you need clarification.

Answer

For such comparison-related operations, NumPy has tools like np.setdiff1d and np.in1d among others. To solve our case, these two would be enough. I would assume that the inputs are NumPy arrays, as then we could use vectorized indexing methods supported by NumPy.

On the first case, we have -

In [97]: fixed = np.array([1,2,6])
    ...: global_arr = np.array([10, 1, 1, 10, 10, 10, 1, 10, 10, 10])
    ...: 

To get the equivalent of list(set(range(len(global_arr)) - set(fixed)) in NumPy, we could make use of np.setdiff1d -

In [98]: np.setdiff1d(np.arange(len(global_arr)),fixed)
Out[98]: array([0, 3, 4, 5, 7, 8, 9])

Next up, we have -

In [99]: local_map = np.array([4, 2, 1, 8, 6])
    ...: local_values = np.array([42, 40, 48, 41, 43])
    ...: 

We were trying to get -

local_free = list(set(range(len(local)) - set(fixed))
local_values[local_free] *= 10

Here, we can use np.in1d to get a mask to be an equivalent for local_free that could be used to index and assign into local_values with NumPy's boolean-indexing method -

In [100]: local_free = ~np.in1d(local_map,fixed)
     ...: local_values[local_free] *= 10
     ...: 

In [101]: local_values
Out[101]: array([420,  40,  48, 410,  43])
Comments