2013-03-01 5 views
1

У меня есть 1-D функция, которая занимает столько времени, чтобы вычислить большой массив с двумя значениями «x», поэтому очень легко создать интерполированную функцию с помощью SciPy а затем вычислить y, используя это, что будет намного быстрее. Однако я не могу использовать функцию интерполяции на массивах с более чем 1-D.Использование функции интерполяции над двумерным массивом

Пример:

# First, I create the interpolation function in the domain I want to work 
x = np.arange(1, 100, 0.1) 
f = exp(x) # a complicated function 
f_int = sp.interpolate.InterpolatedUnivariateSpline(x, f, k=2) 

# Now, in the code I do that 
x = [[13, ..., 1], [99, ..., 45], [33, ..., 98] ..., [15, ..., 65]] 
y = f_int(x) 
# Which I want that it returns y = [[f_int(13), ..., f_int(1)], ..., [f_int(15), ..., f_int(65)]] 

Но возвращается:

ValueError: object too deep for desired array 

Я знаю, что я мог бы перебираем всех членов х, но я не знаю, если это лучший вариант ...

Спасибо!

EDIT:

функция так же будет делать работу:

def vector_op(function, values): 

    orig_shape = values.shape 
    values = np.reshape(values, values.size) 

    return np.reshape(function(values), orig_shape) 

Я попытался np.vectorize, но это слишком медленно ...

ответ

2

Если f_int хочет одномерные данные, вы должны выравниваться ввод, кормить его интерпол, а затем восстановить исходную форму:

>>> x = np.arange(1, 100, 0.1) 
>>> f = 2 * x # a simple function to see the results are good 
>>> f_int = scipy.interpolate.InterpolatedUnivariateSpline(x, f, k=2) 

>>> x = np.arange(25).reshape(5, 5) + 1 
>>> x 
array([[ 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10], 
     [11, 12, 13, 14, 15], 
     [16, 17, 18, 19, 20], 
     [21, 22, 23, 24, 25]]) 
>>> x_int = f_int(x.reshape(-1)).reshape(x.shape) 
>>> x_int 
array([[ 2., 4., 6., 8., 10.], 
     [ 12., 14., 16., 18., 20.], 
     [ 22., 24., 26., 28., 30.], 
     [ 32., 34., 36., 38., 40.], 
     [ 42., 44., 46., 48., 50.]]) 

x.reshape(-1) делает то уплощение, а .reshape(x.shape) возвращает его в исходную форму.

+0

что, вероятно, даст странность по краям – reptilicus

+0

@reptilicus Почему? Я, кажется, не понимаю, что вы можете иметь в виду, извините ... – Jaime

+0

Я думал, что интерполяция приведет к тому, что значения на краях исходного массива будут разными, как только массив будет сплющен, а затем интерполирован, а затем изменен. В основном левые края исходного массива будут интерполированы с правыми краями следующей строки, что может или не может вызвать проблемы. – reptilicus

0

Я хотел бы использовать комбинация list comprehension и map (возможно, существует возможность использовать два вложенных maps, которые мне не хватает)

In [24]: x 
Out[24]: [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 

In [25]: [map(lambda a: a*0.1, x_val) for x_val in x] 
Out[25]: 
[[0.1, 0.2, 0.30000000000000004], 
[0.1, 0.2, 0.30000000000000004], 
[0.1, 0.2, 0.30000000000000004]] 

это только для целей иллюстрации .... заменить lambda a: a*0.1 с вашей функцией, f_int

1

Я думаю, что вы хотите сделать векторизованную функцию в NumPy:

#create some random test data 
test = numpy.random.random((100,100)) 

#a normal python function that you want to apply 
def myFunc(i): 
    return np.exp(i) 

#now vectorize the function so that it will work on numpy arrays 
myVecFunc = np.vectorize(myFunc) 

result = myVecFunc(test) 
Смежные вопросы