List of List of List slicing in Python - python

I have simulated 10000 scenarios for 4 variables during 120 months.
Hence, I have a scenarios list of lists of lists on which to get and element I would have to use scenarios[1][1][1], for example, and this would give me a float.
I want to slice this in two, dividing by the second list. Which means I want to keep the 10000 scenarios for 4 variables for the first 60 months.
How would I go about doing this?
My intuition would tell me to do
scenarios[:][0:60]
but this does not work. Instead of cutting the second list, it cuts the first. What is wrong?
Example:
Q = data.cov().as_matrix() # monthly covariance matrix Q
r=[0.00565,0.00206,0.00368,0.00021] # monthly return
scenarios = [[]]*10000
for i in range(10000):
scenarios[i] = np.random.multivariate_normal(r, Q, size = 120) # monthly scenarios
In my case, Q=
2.167748064990633258e-03 -8.736421379048196659e-05 1.457397098602368978e-04 2.799384719379381381e-06
-8.736421379048196659e-05 9.035930360181909865e-04 3.196576120840064102e-04 3.197146643002681875e-06
1.457397098602368978e-04 3.196576120840064102e-04 2.390042779951682440e-04 2.312645986876262622e-06
2.799384719379381381e-06 3.197146643002681875e-06 2.312645986876262622e-06 4.365866475269951553e-06

Use a list comprehension:
early_scenarios = [x[:60] for x in scenarios]

So, you are trying to use multidimensional slicing on Python list objects, but fundamentally, list objects do not have dimensions. They have no inherent knowledge of their contents, other than the total number of them. But, you *shouldn't be working with list objects at all! Instead, replace this:
scenarios = [[]]*10000
for i in range(10000):
scenarios[i] = np.random.multivariate_normal(r, Q, size = 120) # monthly scenarios
With this:
scenarios = np.random.multivariate_normal(r, Q, size=(1000, 120))
In a REPL:
>>> scenarios = np.random.multivariate_normal(r, Q, size=(1000, 120))
>>> scenarios.shape
(1000, 120, 4)
Then, you can slice to your heart's content in N dimensions using:
scenarios[:, 0:60]
Or, a more wieldy slice:
>>> scenarios[500:520, 0:60]
array([[[-0.05785267, 0.01122828, 0.00786622, -0.00204875],
[ 0.01682276, 0.00163375, 0.00439909, -0.0022255 ],
[ 0.02821342, -0.01634708, 0.01175085, -0.00194007],
...,
[ 0.04918003, -0.02146014, 0.00071328, -0.00222226],
[-0.03782566, -0.00685615, -0.00837397, -0.00095019],
[-0.06164655, 0.02817698, 0.01001757, -0.00149662]],
[[ 0.00071181, -0.00487313, -0.01471801, -0.00180559],
[ 0.05826763, 0.00978292, 0.02442642, -0.00039461],
[ 0.04382627, -0.00804489, 0.00046985, 0.00086524],
...,
[ 0.01231702, 0.01872649, 0.01534518, -0.0022179 ],
[ 0.04212831, -0.05289387, -0.03184881, -0.00078165],
[-0.04361605, -0.01297212, 0.00135886, 0.0057856 ]],
[[ 0.00232622, 0.01773357, 0.00795682, 0.00016406],
[-0.04367355, -0.02387383, -0.00448453, 0.0008559 ],
[ 0.01256918, 0.06565425, 0.05170755, 0.00046948],
...,
[ 0.04457427, -0.01816762, 0.00068176, 0.00186112],
[ 0.00220281, -0.01119046, 0.0103347 , -0.00089715],
[ 0.02178122, 0.03183001, 0.00959293, -0.00057862]],
...,
[[ 0.06338153, 0.01641472, 0.01962643, -0.00256244],
[ 0.07537754, -0.0442643 , -0.00362656, 0.00153777],
[ 0.0505006 , 0.0070783 , 0.01756948, 0.0029576 ],
...,
[ 0.03524508, -0.03547517, -0.00664972, -0.00095385],
[-0.03699107, 0.02256328, 0.00300107, 0.00253193],
[-0.0199608 , -0.00536222, 0.01370301, -0.00131981]],
[[ 0.08601913, -0.00364473, 0.00946769, 0.00045275],
[ 0.01943327, 0.07420857, 0.00109217, -0.00183334],
[-0.04481884, -0.02515305, -0.02357894, -0.00198166],
...,
[-0.01221928, -0.01241903, 0.00928084, 0.00066379],
[ 0.10871802, -0.01264407, 0.00601223, 0.00090526],
[-0.02603179, -0.00413112, -0.006037 , 0.00522712]],
[[-0.02929114, 0.02188803, -0.00427137, 0.00250174],
[ 0.02479416, -0.01470632, -0.01355196, 0.00338125],
[-0.01915726, -0.00869161, 0.01451885, -0.00137969],
...,
[ 0.05398784, -0.00834729, -0.00437888, 0.00081602],
[ 0.00626345, -0.0261016 , -0.01484753, 0.00060499],
[ 0.05427697, 0.04006612, 0.03371313, -0.00203731]]])
>>>

You need to explicitly slice each secondary list, either in a loop or in list comprehensions. I built a 10x10 set of lists so you have to change the indexing to fit your problem:
x = []
for a in range(10):
x.append([10*a+n for n in range(10)])
# x is now a list of 10 lists, each of which has 10 elements
print(x)
x1 = [a[:5] for a in x]
# x1 is a list of containing the low elements of the secondary lists
x2 = [a[5:] for a in x]
# x2 is a list containing the high elements of the secondary lists
print(x1, x2)

Python slicing doesn't consider all dimension like this. Your expression makes a copy of the entire list, scenarios[:], and then takes the first 60 elements of the copy. You need to write a comprehension to grab the elements you want.
Perhaps
[scenarios[x][y][z]
for x in range(len(scenarios))
for y in range(60)
for z in range(len(scenarios[0][0])) ]

Related

Create a new array of all values from an array with step

I am new to Python. I would like to create a new array, that contains all values from an existing array with the step.
I tried to implement it but I think there is another way to have better performance. Any try or recommendation is highly appreciated.
Ex: Currently, I have:
An array: 115.200 values (2D dimension)
Step: 10.000
....
array([[ 0.2735, -0.308 ],
[ 0.287 , -0.3235],
[ 0.2925, -0.324 ],
[ 0.312 , -0.329 ],
[ 0.3275, -0.345 ],
[ 0.3305, -0.352 ],
[ 0.332 , -0.3465],
...
[ 0.3535, -0.353 ],
[ 0.361 , -0.3445],
[ 0.3545, -0.329 ]])
Expectation: A new array is sliced the array above by step of 10.000.
Below is my code:
for x in ecg_data:
number_samples_by_duration_exp_temp = 10000
# len(ecg_property.sample) = 115200
times = len(ecg_property.sample) / number_samples_by_duration_exp_temp
index_by_time = [int(y)*number_samples_by_duration_exp_temp for y in np.arange(1, times, 1)]
list = []
temp = 0
for z in index_by_time:
arr_samples_by_duration = ecg_property.sample[temp:z]
list.append(arr_samples_by_duration)
temp = z
numpy can not be used for this purpose as len(ecg_property.sample) #115,200 is not fully divisible by number_samples_by_duration_exp_temp #10,000 and numpy cannot allow elements of varying lengths :)
You can try list comprehension.
result_list = [ecg_property.sample[temp :temp+step] for temp in np.arange(times)*step ]
where
step=10000 and times = len(ecg_property.sample) / step
It can be further modified if needed and as per requirement.
(You can try out each step in above line of code in this answer and see the output to understand each step )
Hope this works out.
ty!

Numpy: is this the fastest way to slice+'leftover' a mulltidim array?

Assume I have a multidimensional Numpy Array. Now I want to:
Slice out a certain row range defined by startIndex and endIndex.
Get a array with the original array minus the slice (so the left over).
The code below does this trick, however is this the most performance one?
Because my array is very big, can I (memory neutral) slice out the original array so that afterwards the original array is the left over. So except some overhead for the header of the new array this will cost no additional memory?
Is my snippet below (with creating new arrays), the the most efficient solution if we retain the original array?
Example:
import numpy as np
X = np.random.random((6, 2))
print('Orig',X)
startIndex = 2
endIndex = 4
print('Slice ',X[startIndex:endIndex])
print('LeftOver ',np.concatenate((X[:startIndex-1],X[endIndex:])))
Output:
Orig [[ 0.94661646 0.3911347 ]
[ 0.6807441 0.676658 ]
[ 0.81109554 0.18089991]
[ 0.6161699 0.19907537]
[ 0.12859196 0.34866049]
[ 0.22283545 0.04949782]]
Slice [[ 0.81109554 0.18089991]
[ 0.6161699 0.19907537]]
LeftOver [[ 0.94661646 0.3911347 ]
[ 0.12859196 0.34866049]
[ 0.22283545 0.04949782]]
Concatenate make a copy, and you need it if order matters.
But if your slices are slim, and order doesn't matter, a more economic way can be:
import numpy as np
size=6
X = np.random.random((size, 2))
print('Orig\n',X)
startIndex = 3
endIndex = 5
Slice=X[startIndex:endIndex].copy()
length = min(endIndex-startIndex,size-endIndex) # to check overlap
X[startIndex:startIndex+length]=X[-length:]
Left=X[:size-len(Slice)]
print('Slice\n',Slice)
print('LeftOver\n',Left)
because at most 2x the size of the slice is copied, not the whole array.
it gives:
Orig
[[ 0.39351322 0.42100711]
[ 0.14793363 0.12149344]
[ 0.94524844 0.22004186]
[ 0.816418 0.35630767]
[ 0.37781821 0.12336287]
[ 0.65995888 0.23812275]]
Slice
[[ 0.816418 0.35630767]
[ 0.37781821 0.12336287]]
LeftOver
[[ 0.39351322 0.42100711]
[ 0.14793363 0.12149344]
[ 0.94524844 0.22004186]
[ 0.65995888 0.23812275]]

Boolean sum with numpy finding matching pairs

I am trying to find mirror images in a numpy array. In particular, (x,y) == (y,x) but I want to rule out tuples with identical values (x,x).
Given a numpy array pckList with the size (198L,3L) containing floats.
I have the following code:
np.sum([x==pckLst[:,2] for x in pckLst[:,1]])
Which returns a given number, lets say 73
np.sum([x==pckLst[:,2] for x in pckLst[:,1]] and [x==pckLst[:,1] for x in pckLst[:,1]])
Returns a larger number, lets say 266.
Can someone please explain how this comes about?
I thought the first line returns True, when seen as tuples (x,y) == (any,y) and the second line returns only true when (x,y) == (y,x).
Is this correct?
EDIT:
Further explaination:
pckLst=[[ 112.066, 6.946, 6.938],
[ 111.979, 6.882, 7.634],
[ 112.014, 6.879, 7.587],
[ 112.005, 6.887, 7.554],
[ 111.995, 6.88, 6.88 ],
[ 112.048, 6.774, 6.88 ],
[ 111.808, 7.791, 7.566],
[ 111.802, 6.88, 6.774]]
Now I would like to find [ 112.048, 6.774, 6.88 ], since (6.88, 6.774) == (6.774, 6.88). However, [ 111.995, 6.88, 6.88 ] should not be considered a match.
Rather than commenting on your code here is a simpler implementation
a=np.array([[1,1,10],[1,2,20],[2,1,30],[1,3,40],[2,3,50]])
xy= a[:,:2].tolist()
[[x,y,z] for [x,y,z] in a if [y,x] in xy and x!=y]
[[1, 2, 20], [2, 1, 30]]
The arguments to "and" in your example are python-lists. The truth value of a list is True if it is not empty. Thats why you get a bigger sum in the latter case.
This will return the sum of elements with (x,y) == (y,x). It obviously only works if your just interested in the sum and not particular indices:
import numpy
pckLst = numpy.array([[ 112.066, 6.946, 6.938],
[ 111.979, 6.882, 7.634],
[ 112.014, 6.879, 7.587],
[ 112.005, 6.887, 7.554],
[ 111.995, 6.88, 6.88 ],
[ 112.048, 6.774, 6.88 ],
[ 111.808, 7.791, 7.566],
[ 111.802, 6.88, 6.774]])
coords = pckLst[:,1:]
equal_ids = numpy.ravel(coords[:,:1] != coords[:,1:])
unequal_coords = coords[equal_ids]
flipped = numpy.fliplr(unequal_coords)
coords_tuple_set = set(tuple(map(tuple, unequal_coords)))
flipped_tuple_set = set(tuple(map(tuple, flipped)))
print coords_tuple_set
print flipped_tuple_set
# need to devide by two, because we get (x,y) and (y,x) by the intersection
print "number of mirrored points:",
print len(coords_tuple_set.intersection(flipped_tuple_set))/2

Populating a numpy matrix using fromfunction and an array

I have an array called phases, let's say it looks like this:
phases = numpy.random.uniform(0,1,10)
I now want to populate a matrix where every row is some function f applied to a successive index of phases, and every column is a multiple of it, looking something like this:
[[ f(phases[0]) f(2*phases[0]) f(3*phases[0]) ]
[ f(phases[1]) f(2*phases[1]) f(3*phases[1]) ]
... ... ...
[ f(phases[9]) f(2*phases[9]) f(3*phases[9]) ]]
We can say f is something simple for the sake of example, like f(x) = x+1.
So I figured I would just use numpy.fromfunction as follows:
numpy.fromfunction(lambda i,j: (j+1)*phases[i]+1,
(phases.size, 3), dtype=float)
but this gives me an error:
IndexError: arrays used as indices must be of integer (or boolean) type
How can I access the ith element of phases within fromfunction?
Or is this the wrong approach to take?
numpy.fromfunction does not work as expected, its documentation is also misleading.
The function is not called for each cell, but once with all indices.
def fromfunction(function, shape, **kwargs):
dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args,**kwargs)
So now, to get your result, you can do the following :
In [57]: vf = numpy.vectorize(f)
In [58]: vf(numpy.outer(phases, numpy.arange(1,4)))
Out[58]:
array([[ 1.87176928, 2.74353857, 3.61530785],
[ 1.23090955, 1.4618191 , 1.69272866],
[ 1.29294723, 1.58589445, 1.87884168],
[ 1.05863891, 1.11727783, 1.17591674],
[ 1.28370397, 1.56740794, 1.85111191],
[ 1.87210286, 2.74420573, 3.61630859],
[ 1.08652975, 1.1730595 , 1.25958925],
[ 1.33835545, 1.6767109 , 2.01506634],
[ 1.74479635, 2.48959269, 3.23438904],
[ 1.76381301, 2.52762602, 3.29143903]])
outer will perform the outer product of two vectors, exactly what you want except from the function.
Your function must be able to handle arrays. For non-trivial operations, you will have to vectorize the function, so that it will be applied cell-by-cell. In your example, you don't have to care.
I think the easiest approach that follows NumPy idioms (and therefore vectorizes well) is to make the matrix you want first, and then apply your function f to it.
>>> phases = numpy.random.uniform(0,1,10)
>>> phases = phases.reshape((10, 1))
>>> phases = np.tile(phases, (1, 3))
This gives you the a matrix (actually an ndarray) of the form
[[ phases[0] 2*phases[0] 3*phases[0] ]
[ phases[1] 2*phases[1] 3*phases[1] ]
... ... ...
[ phases[9] 2*phases[9] 3*phases[9] ]]
which you can then apply your function to.
>>> def f(x):
... return numpy.sin(x)
>>> f(phases)
array([[ 0.56551297, 0.93280166, 0.97312359],
[ 0.38704365, 0.71375602, 0.92921009],
[ 0.62778184, 0.97731738, 0.89368501],
[ 0.0806512 , 0.16077695, 0.23985519],
[ 0.4140241 , 0.75374405, 0.95819095],
[ 0.25929821, 0.50085902, 0.70815838],
[ 0.25399811, 0.49133634, 0.69644753],
[ 0.7754078 , 0.97927926, 0.46134512],
[ 0.53301912, 0.90197836, 0.99331443],
[ 0.44019133, 0.79049912, 0.9793933 ]])
This only works if your function, f, is "vectorized", which is to say that it accepts an ndarray and operates element-wise on that array. If that's not the case, then you can use numpy.vectorize to get a version of that function that does so.
>>> import math
>>> def f(x):
... return math.sin(x)
>>> f(phases)
TypeError: only length-1 arrays can be converted to Python scalars
>>> f = numpy.vectorize(f)
>>> f(phases)
array([[ 0.56551297, 0.93280166, 0.97312359],
[ 0.38704365, 0.71375602, 0.92921009],
[ 0.62778184, 0.97731738, 0.89368501],
[ 0.0806512 , 0.16077695, 0.23985519],
[ 0.4140241 , 0.75374405, 0.95819095],
[ 0.25929821, 0.50085902, 0.70815838],
[ 0.25399811, 0.49133634, 0.69644753],
[ 0.7754078 , 0.97927926, 0.46134512],
[ 0.53301912, 0.90197836, 0.99331443],
[ 0.44019133, 0.79049912, 0.9793933 ]])

Python/Numpy - Get Index into Main Array from Subset

Say I have a 100 element numpy array. I perform some calculation on a subset of this array - maybe 20 elements where some condition is met. Then I pick an index in this subset, how can I (efficiently) recover the index in the first array? I don't want to perform the calculation on all values in a because it is expensive, so I only want to perform it where it is required (where that condition is met).
Here is some pseudocode to demonstrate what I mean (the 'condition' here is the list comprehension):
a = np.arange(100) # size = 100
b = some_function(a[[i for i in range(0,100,5)]]) # size = 20
Index = np.argmax(b)
# Index gives the index of the maximum value in b,
# but what I really want is the index of the element
# in a
EDIT:
I wasn't being very clear, so I've provided a more full example. I hope this makes it more clear about what my goal is. I feel like there is some clever and efficient way to do this, without some loops or lookups.
CODE:
import numpy as np
def some_function(arr):
return arr*2.0
a = np.arange(100)*2. # size = 100
b = some_function(a[[i for i in range(0,100,5)]]) # size = 20
Index = np.argmax(b)
print Index
# Index gives the index of the maximum value in b, but what I really want is
# the index of the element in a
# In this specific case, Index will be 19. So b[19] is the largest value
# in b. Now, what I REALLY want is the index in a. In this case, that would
# 95 because some_function(a[95]) is what made the largest value in b.
print b[Index]
print some_function(a[95])
# It is important to note that I do NOT want to change a. I will perform
# several calculations on SOME values of a, then return the indices of 'a' where
# all calculations meet some condition.
I am not sure if I understand your question. So, correct me if I am wrong.
Let's say you have something like
a = np.arange(100)
condition = (a % 5 == 0) & (a % 7 == 0)
b = a[condition]
index = np.argmax(b)
# The following should do what you want
a[condition][index]
Or if you don't want to work with masks:
a = np.arange(100)
b_indices = np.where(a % 5 == 0)
b = a[b_indices]
index = np.argmax(b)
# Get the value of 'a' corresponding to 'index'
a[b_indices][index]
Is this what you want?
Use a secondary array, a_index, which is just the indices of the elements of a, so a_index[3,5] = (3,5). Then you can get the original index as a_index[condition == True][Index].
If you can guarantee that b is a view on a, you can use the memory layout information of the two arrays to find a translation between b's and a's indices.
Does something like this work ?
mask = S == 1
ind_local = np.argmax(X[mask])
G = np.ravel_multi_index(np.where(mask), mask.shape)
ind_global = np.unravel_index(G[ind_local], mask.shape)
return ind_global
This returns the global index of the argmax.
Normally you'd store the index based on the condition before you made any changes to the array. You use the index to make the changes.
If a is your array:
>>> a = np.random.random((10,5))
>>> a
array([[ 0.22481885, 0.80522855, 0.1081426 , 0.42528799, 0.64471832],
[ 0.28044374, 0.16202575, 0.4023426 , 0.25480368, 0.87047212],
[ 0.84764143, 0.30580141, 0.16324907, 0.20751965, 0.15903343],
[ 0.55861168, 0.64368466, 0.67676172, 0.67871825, 0.01849056],
[ 0.90980614, 0.95897292, 0.15649259, 0.39134528, 0.96317126],
[ 0.20172827, 0.9815932 , 0.85661944, 0.23273944, 0.86819205],
[ 0.98363954, 0.00219531, 0.91348196, 0.38197302, 0.16002007],
[ 0.48069675, 0.46057327, 0.67085243, 0.05212357, 0.44870942],
[ 0.7031601 , 0.50889065, 0.30199446, 0.8022497 , 0.82347358],
[ 0.57058441, 0.38748261, 0.76947605, 0.48145936, 0.26650583]])
And b is your subarray:
>>> b = a[2:4,2:7]
>>> b
array([[ 0.16324907, 0.20751965, 0.15903343],
[ 0.67676172, 0.67871825, 0.01849056]])
It can be shown that a still owns the data in b:
>>> b.base
array([[ 0.22481885, 0.80522855, 0.1081426 , 0.42528799, 0.64471832],
[ 0.28044374, 0.16202575, 0.4023426 , 0.25480368, 0.87047212],
[ 0.84764143, 0.30580141, 0.16324907, 0.20751965, 0.15903343],
[ 0.55861168, 0.64368466, 0.67676172, 0.67871825, 0.01849056],
[ 0.90980614, 0.95897292, 0.15649259, 0.39134528, 0.96317126],
[ 0.20172827, 0.9815932 , 0.85661944, 0.23273944, 0.86819205],
[ 0.98363954, 0.00219531, 0.91348196, 0.38197302, 0.16002007],
[ 0.48069675, 0.46057327, 0.67085243, 0.05212357, 0.44870942],
[ 0.7031601 , 0.50889065, 0.30199446, 0.8022497 , 0.82347358],
[ 0.57058441, 0.38748261, 0.76947605, 0.48145936, 0.26650583]])
You can make changes to both a and b in two ways:
>>> b+=1
>>> b
array([[ 1.16324907, 1.20751965, 1.15903343],
[ 1.67676172, 1.67871825, 1.01849056]])
>>> a
array([[ 0.22481885, 0.80522855, 0.1081426 , 0.42528799, 0.64471832],
[ 0.28044374, 0.16202575, 0.4023426 , 0.25480368, 0.87047212],
[ 0.84764143, 0.30580141, 1.16324907, 1.20751965, 1.15903343],
[ 0.55861168, 0.64368466, 1.67676172, 1.67871825, 1.01849056],
[ 0.90980614, 0.95897292, 0.15649259, 0.39134528, 0.96317126],
[ 0.20172827, 0.9815932 , 0.85661944, 0.23273944, 0.86819205],
[ 0.98363954, 0.00219531, 0.91348196, 0.38197302, 0.16002007],
[ 0.48069675, 0.46057327, 0.67085243, 0.05212357, 0.44870942],
[ 0.7031601 , 0.50889065, 0.30199446, 0.8022497 , 0.82347358],
[ 0.57058441, 0.38748261, 0.76947605, 0.48145936, 0.26650583]])
Or:
>>> a[2:4,2:7]+=1
>>> a
array([[ 0.22481885, 0.80522855, 0.1081426 , 0.42528799, 0.64471832],
[ 0.28044374, 0.16202575, 0.4023426 , 0.25480368, 0.87047212],
[ 0.84764143, 0.30580141, 1.16324907, 1.20751965, 1.15903343],
[ 0.55861168, 0.64368466, 1.67676172, 1.67871825, 1.01849056],
[ 0.90980614, 0.95897292, 0.15649259, 0.39134528, 0.96317126],
[ 0.20172827, 0.9815932 , 0.85661944, 0.23273944, 0.86819205],
[ 0.98363954, 0.00219531, 0.91348196, 0.38197302, 0.16002007],
[ 0.48069675, 0.46057327, 0.67085243, 0.05212357, 0.44870942],
[ 0.7031601 , 0.50889065, 0.30199446, 0.8022497 , 0.82347358],
[ 0.57058441, 0.38748261, 0.76947605, 0.48145936, 0.26650583]])
>>> b
array([[ 1.16324907, 1.20751965, 1.15903343],
[ 1.67676172, 1.67871825, 1.01849056]])
Both are equivalent and neither is more expensive than the other. Therefore as long as you retain the indices that created b from a, you can always view the changed data in the base array. Often it is not even necessary to create a subarray when doing operations on slices.
Edit
This assumes some_func returns the indices in the subarray where some condition is true.
I think when a function returns indices and you only want to feed that function a subarray, you still need to store the indices of that subarray and use them to get the base array indices. For example:
>>> def some_func(a):
... return np.where(a>.8)
>>> a = np.random.random((10,4))
>>> a
array([[ 0.94495378, 0.55532342, 0.70112911, 0.4385163 ],
[ 0.12006191, 0.93091941, 0.85617421, 0.50429453],
[ 0.46246102, 0.89810859, 0.31841396, 0.56627419],
[ 0.79524739, 0.20768512, 0.39718061, 0.51593312],
[ 0.08526902, 0.56109783, 0.00560285, 0.18993636],
[ 0.77943988, 0.96168229, 0.10491335, 0.39681643],
[ 0.15817781, 0.17227806, 0.17493879, 0.93961027],
[ 0.05003535, 0.61873245, 0.55165992, 0.85543841],
[ 0.93542227, 0.68104872, 0.84750821, 0.34979704],
[ 0.06888627, 0.97947905, 0.08523711, 0.06184216]])
>>> i_off, j_off = 3,2
>>> b = a[i_off:,j_off:] #b
>>> i = some_func(b) #indicies in b
>>> i
(array([3, 4, 5]), array([1, 1, 0]))
>>> map(sum, zip(i,(i_off, j_off))) # indicies in a
[array([6, 7, 8]), array([3, 3, 2])]
Edit 2
This assumes some_func returns a modified copy of the subarray b.
Your example would look something like this:
import numpy as np
def some_function(arr):
return arr*2.0
a = np.arange(100)*2. # size = 100
idx = np.array(range(0,100,5))
b = some_function(a[idx]) # size = 20
b_idx = np.argmax(b)
a_idx = idx[b_idx] # indices in a translated from indices in b
print b_idx, a_idx
print b[b_idx], a[a_idx]
assert b[b_idx] == 2* a[a_idx] #true!

Categories

Resources