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.

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])
``````
Source (Stackoverflow)