简体   繁体   中英

Passing np.array indexes into functions

I have a Django model which provides access to numpy array.

I want to create a generator which accepts two arguments:

  1. A Queryset of the model I just mentioned, and
  2. A numpy array slice/index syntax

This generator should iterate through the Queryset and yield the numpy array associated with each model instance in the Queryset. Instead of having to always yield the full numpy array, I would like to be able to specify the slice I want to retrieve.

I tried doing this by passing a string in, and then using eval(string), but it doesn't like colons.

for example, this works:

numpy_array[eval("0,0")]

but this does not:

numpy_array[eval(":")]

Can anyone think of a way to do this?

Note: I do not know Django. I am assuming you can only pass a string to the Django model.


You could eval the string "slice(...)" :

In [101]: arr = np.random.random((100,))

In [102]: arr[eval("slice(6,10)")]
Out[102]: array([ 0.60968632,  0.17116998,  0.24861622,  0.37071511])

or, if you have a 2D-array, you could even pass a stringified tuple of slices:

In [105]: arr = arr.reshape(10,10)    

In [107]: arr[eval("slice(6,10), slice(2,5)")]
Out[107]: 
array([[ 0.23903737,  0.07691556,  0.08544998],
       [ 0.79273288,  0.73710837,  0.11193991],
       [ 0.65617212,  0.53528755,  0.53514291],
       [ 0.01626145,  0.59864093,  0.71240672]])

Note, however, that eval is inherently unsafe if the string comes from user input.


Here is a safer way: Pass a stringified list of tuples. Each tuple represents a slice:

In [108]: import ast
In [109]: ast.literal_eval("[(6,10), (2,5)]")
Out[109]: [(6, 10), (2, 5)]
In [110]: [slice(*item) for item in ast.literal_eval("[(6,10), (2,5)]")]
Out[110]: [slice(6, 10, None), slice(2, 5, None)]

In [111]: arr[[slice(*item) for item in ast.literal_eval("[(6,10), (2,5)]")]]
Out[111]: 
array([[ 0.23903737,  0.07691556,  0.08544998],
       [ 0.79273288,  0.73710837,  0.11193991],
       [ 0.65617212,  0.53528755,  0.53514291],
       [ 0.01626145,  0.59864093,  0.71240672]])

In [113]: arr[[slice(*item) for item in ast.literal_eval("[(0,1), (0,1)]")]]
Out[113]: array([[ 0.77409234]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM