Alex Cushley
Alex Cushley

Reputation: 95

How can I interpolate values from two lists (in Python)?

I am relatively new to coding in Python. I have mainly used MatLab in the past and am used to having vectors that can be referenced explicitly rather than appended lists. I have a script where I generate a list of x- and y- (z-, v-, etc) values. Later, I want to interpolate and then print a table of the values at specified points. Here is a MWE. The problem is at line 48:

yq  = interp1d(x_list, y_list, xq(nn))#interp1(output1(:,1),output1(:,2),xq(nn))

I'm not sure I have the correct syntax for the last two lines either:

table[nn] = ('%.2f' %xq, '%.2f' %yq)

print(table)

Here is the full script for the MWE:

#This script was written to test how to interpolate after data was created in a loop and stored as a list. Can a list be accessed explicitly like a vector in matlab?
#
from scipy.interpolate import interp1d
from math import *  #for ceil 
from astropy.table import Table #for Table
import numpy as np 
# define the initial conditions
x = 0               # initial x position
y = 0               # initial y position
Rmax = 10           # maxium range

""" initializing variables for plots"""
x_list = [x]
y_list = [y]

""" define functions"""
# not necessary for this MWE

"""create sample data for MWE"""
# x and y data are calculated using functions and appended to their respective lists
h = 1
t = 0 
tf = 10 
N=ceil(tf/h)

# Example of interpolation without a loop: https://docs.scipy.org/doc/scipy/tutorial/interpolate.html#d-interpolation-interp1d
#x = np.linspace(0, 10, num=11, endpoint=True)
#y = np.cos(-x**2/9.0)
#f = interp1d(x, y)

for i in range(N):
    x = h*i
    y = cos(-x**2/9.0)

    """ appends selected data for ability to plot"""
    x_list.append(x)
    y_list.append(y)


## Interpolation after x- and y-lists are already created
intervals = 0.5
nfinal = ceil(Rmax/intervals)
NN = nfinal+1 # length of table
dtype = [('Range (units?)', 'f8'), ('Drop? (units)', 'f8')]
table = Table(data=np.zeros(N, dtype=dtype))
for nn in range(NN):#for nn = 1:NN
    xq  = 0.0 + (nn-1)*intervals    #0.0 + (nn-1)*intervals
    yq  = interp1d(x_list, y_list, xq(nn))#interp1(output1(:,1),output1(:,2),xq(nn))
    table[nn] = ('%.2f' %xq, '%.2f' %yq)

print(table)

Your help and patience will be greatly appreciated!

Best regards,

Alex

Upvotes: 0

Views: 848

Answers (1)

Tempman383838
Tempman383838

Reputation: 574

Your code has some glaring issues that made it really difficult to understand. Let's first take a look at some things I needed to fix:

for i in range(N):
    x = h*1
    y = cos(-x**2/9.0)

    """ appends selected data for ability to plot"""
    x_list.append(x)
    y_list.append(y)

You are appending a single value without modifying it. What I presume you wanted is down below.

intervals = 0.5
nfinal = ceil(Rmax/intervals)
NN = nfinal+1 # length of table
dtype = [('Range (units?)', 'f8'), ('Drop? (units)', 'f8')]
table = Table(data=np.zeros(N, dtype=dtype))
for nn in range(NN):#for nn = 1:NN
    xq  = 0.0 + (nn-1)*intervals    #0.0 + (nn-1)*intervals
    yq  = interp1d(x_list, y_list, xq(nn))#interp1(output1(:,1),output1(:,2),xq(nn))
    table[nn] = ('%.2f' %xq, '%.2f' %yq)

This is where things get strange. First: use pandas tables, this is the more popular choice. Second: I have no idea what you are trying to loop over. What I presume you wanted was to vary the number of points for the interpolation, which I have done so below. Third: you are trying to interpolate a point, when you probably want to interpolate over a range of points (...interpolation). Lastly, you are using the interp1d function incorrectly. Please take a look at the code below or run it here; let me know what you exactly wanted (specifically: what should xq / xq(nn) be?), because the MRE you provided is quite confusing.

from scipy.interpolate import interp1d
from math import *
import numpy as np 


Rmax = 10
h = 1
t = 0 
tf = 10 
N = ceil(tf/h)

x = np.arange(0,N+1)
y = np.cos(-x**2/9.0)

interval = 0.5
NN = ceil(Rmax/interval) + 1

ip_list = np.arange(1,interval*NN,interval)

xtable = []
ytable = []

for i,nn in enumerate(ip_list):
    f = interp1d(x,y)
    x_i = np.arange(0,nn+interval,interval)
    xtable += [x_i]
    ytable += [f(x_i)]

[print(i) for i in xtable]
[print(i) for i in ytable]

Upvotes: 2

Related Questions