1

I have a program where I want the user to choose a temperature (T_user), whatever he wants. Knowing that I have a temperature array: T=np.array([10,20,30,50,100,150,200]). I have found a way to get the index and closest value for T_user compared to the values in T. I then have X=np.array([1,2,3,4,5,6]) and Y=np.array([3,6,9,12,15,18]) using numpy.interp(). Now lets say that T_user=12 and that X,Y are respectively linked to T[0]=10 and T[1]=20 how can I create a new array interpolated with X,T arrays and "the distance"/ratio from T_user to T[0]=10 and T[1]=20. Let me know if this is not clear at all.

Michael
  • 35
  • 6
  • Can you explicitly show both the input and the desired output examples? – quasi-human Feb 19 '22 at 07:44
  • Well the input would be `T_user` and the output would be an array of `Len(X)=6` and then each values of `X` and `Y ` would be interpolated between one another. Example: `Y=np.array([1,2,3]), Y=np.array([3,6,9)], T_user=15` then the result would be in this case: `Interpo=np.array([2,4,6])`. – Michael Feb 19 '22 at 09:45
  • little mistake above, it is `X=np.array([1,2,3])` – Michael Feb 19 '22 at 10:31
  • Hi, @Michael. It is not clear what you are looking for. From your comment, It seems that you want to average two arrays, which in this case you can obtain as `Interpo = (X+Y)/2`. Nevertheless, it seems from your question that you are looking for something else. – azelcer Feb 21 '22 at 01:36
  • HI, @azelcer. Yeah ils kind of hard for me for explain it clearly. But what I meant is I want the interpolation to be proportional (linear interpolation) regarding the `T_user`. Another example: `T_user = 12` (closer to 10 (linked to X) than 20 (linked to Y)) thus we would get: `Interpo=np.array([1.4, 2.8, 4.2)] `. The values of Interpo are "closer" to X than Y because T_user is closer to 10, by a certain proportional coefficient. – Michael Feb 21 '22 at 09:29
  • Ps the foloowing code worked (using relative differences, but I wanted to do it using np.interp in order to be more efficient): ` import numpy as np` `T_user = 12 T = np.array([10, 20, 30, 50, 70, 100, 150, 200, 250, 300])` ` W1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # array linked to T[0]=10 ` `W2 = np.array([3, 6, 9, 12, 15, 18, 21, 24, 27, 30]) # array linked to T[1]=20 ` `x1 = abs((T_user-10)/10)` `x2 = abs((T_user-20)/10)` `W3 = (W1*x2)+(W2*x1) print(x1, x2, W3)` – Michael Feb 21 '22 at 09:32
  • output: ` 0.2 0.8 [ 1.4 2.8 4.2 5.6 7. 8.4 9.8 11.2 12.6 14. ] ` – Michael Feb 21 '22 at 09:35

1 Answers1

0

You can use the apply_along_axis method:

Code:

import numpy as np

T = np.array([10, 20, 30, 50, 100, 150, 200])
W1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
W2 = np.array([3, 6, 9, 12, 15, 18, 21, 24, 27, 30])

T_user = 12

# Get the neighbor values
t1 = T[T<=T_user].max(initial=T.min())
t2 = T[T_user<=T].min(initial=T.max())

# Interpolate the values
arr_interp = np.apply_along_axis(lambda e: np.interp(T_user, [t1, t2], e), 1, np.stack([W1, W2]).T)

Tests:

f = lambda t: np.apply_along_axis(lambda e: np.interp(t, [T[T<=t].max(initial=T.min()), T[t<=T].min(initial=T.max())], e), 1, np.stack([W1, W2]).T)

T_user = 12
np.testing.assert_array_equal(f(T_user), np.array([1.4, 2.8, 4.2, 5.6, 7.0, 8.4, 9.8, 11.2, 12.6, 14.0]))

T_user = 15
np.testing.assert_array_equal(f(T_user), np.array([ 2.,  4.,  6.,  8., 10., 12., 14., 16., 18., 20.]))

T_user = 31
np.testing.assert_array_equal(f(T_user), np.array([ 1.1,  2.2,  3.3,  4.4,  5.5,  6.6,  7.7,  8.8,  9.9, 11. ]))

T_user = 0
np.testing.assert_array_equal(f(T_user), np.array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]))

T_user = 10
np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))

T_user = 100
np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))

T_user = 200
np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))

T_user = 300
np.testing.assert_array_equal(f(T_user), np.array([ 3.,  6.,  9., 12., 15., 18., 21., 24., 27., 30.]))

Explanation:

If you have a minimal sample dataset as follows, what is the interpolation going to be like in my implementation?

T = np.array([10, 20])
W1 = np.array([1,])
W2 = np.array([3,])

# Case.1 (T_user = 12)

enter image description here

# Case.2 (T_user = 5)

enter image description here

# Case.3 (T_user = 10)

enter image description here

# Case.4 (T_user = 25)

enter image description here

quasi-human
  • 1,898
  • 1
  • 2
  • 13
  • 1
    That is exactly what I was looking for! I tried the numpy.interp function as I said but it wasn't enough because I needed to compare multiple arrays. Thanks again @quasi-human and congrats for understanding what I wanted to get as a result ! In my set of data I have an array W for each temperature so I'll implement your technic. – Michael Feb 23 '22 at 06:43
  • And if you have more time could you quickly explain what is the `lambda` function doing ? Because I've never used it. Also why did you use `np.stack([W1, W2]).T` – Michael Feb 23 '22 at 06:49
  • As for the `lambda` function itself, this might be useful to understand how it is convenient: https://stackoverflow.com/questions/890128/how-are-lambdas-useful/890188#890188 – quasi-human Feb 23 '22 at 12:52
  • As for `np.stack`, we actually need a pair of [1, 3], [2, 6], [3, 9] etc to calculate the target values. We can't carry out the necessary operation if arrays exist separately, like [1, 2, 3, ...], [3, 6, 9, ...]. So we have to combine W1 and W2. Afterwards, we apply the interpolation to the pair of interest. Do you know what I mean? – quasi-human Feb 23 '22 at 12:59
  • Okay I get it, the `lambda` function is really convenient, very quick instead of defining another function. And concerning the `np.stack` is it kind of similar to `np.concatenate` ? – Michael Feb 23 '22 at 15:10
  • `np.stack` concatenates two arrays on a new axis. `np.concatenate` does on an existing axis. They are similar to each other, but still there is a little difference. Check this post: https://stackoverflow.com/questions/70015993/what-is-the-difference-between-concatenate-and-stack-in-numpy – quasi-human Feb 23 '22 at 15:14
  • 1
    Oh okay I see thanks again for your help. I also tested your code on a new set of data and had to put 2 instead of your 1 otherwise it told me that xs and fs had not the same size, I'll look into axis in NumPy. – Michael Feb 23 '22 at 15:36