Ошибка индекса: индекс x выходит за рамки для оси 0 с размером x

#python #matplotlib #numerical-methods #numerical-integration #index-error

Вопрос:

Я собираюсь построить график функции скорости времени, когда соберу функцию ускорения времени. Однако я получаю код ошибки IndexError: index 51 is out of bounds for axis 0 with size 51 , 51-это последний индекс моих данных, так как мои данные настроены следующим образом: f.write(str(akselerasjon) " " str(tid) "n") , собрал их в МикроПитоне. Однако ошибка возникает в python, где я имею дело с данными.

Это мой код:

 # -*- coding: utf-8 -*-
"""
Created on Sat May 22 21:04:05 2021

@author: Petter Jansen Ytterdahl
"""

from matplotlib import pyplot as plt
import numpy as np

def rektangelmetoden(aks, tid):
    a_v = len(tid)
    vm = [0]
    t_v = 0
    
    for i in range(a_v - 1):
        h = tid[i   1] - tid[i]
        t_v  = aks[i] * h
        vm.append(t_v)
    return(vm)    

f = np.loadtxt("målinger.txt", float, skiprows = 0)
acceleration = f[:, 0]
time = f[:, 1]

gravitational_acceleration = 9.81 
mass = 0.5
k = 0.01 

m_v = []
m_t = []
t_start = 0
t_end = 5
steps = 1000
length_steps = (t_end-t_start)/(steps-1) 
 
velocity = np.zeros(steps) 
time = np.zeros(steps) 

for i in range(steps-1):
    velocity[i 1] = velocity[i]   length_steps * (gravitational_acceleration - k * velocity[i]**2 / mass)
    time[i 1] = time[i]   length_steps 

velocity_r = rektangelmetoden(acceleration, time)

plt.plot(time, velocity, color = "b", label = "Teoretisk modell")
plt.plot(time, velocity_r, color = "r", label = "målinger")
plt.xlabel("Time [s]")
plt.ylabel("Velocity [m/s]")
plt.title("Micro:Bit in parachute")
plt.grid()
plt.legend()
 

Ошибка возникает в этой строке (строка 18):

 t_v  = aks[i] * h
 

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

Комментарии:

1. Почему бы вам не попробовать отладку, например, печать i И len(aks) перед строкой, в которой произошла ошибка, чтобы вы могли проверить, что i это всегда <= len(aks)

2. Вы имеете дело с производными инструментами, поэтому каждый раз теряете очко. Возможно, вы захотите добавить начальное значение ускорения 0 в свой список: aks.insert(0, 0) . В качестве альтернативы, rektangelmetoden вероятно, дает результаты, близкие к scipy.integrate.trapezoid .

3. я знаю, что я сделал, но это сработало, так что спасибо за помощь/усилия, ребята 🙂

Ответ №1:

Попробуйте изменить свой код на этот:

 # -*- coding: utf-8 -*-
"""
Created on Sat May 22 21:04:05 2021

@author: Petter Jansen Ytterdahl
"""

from matplotlib import pyplot as plt
import numpy as np


def rektangelmetoden(aks, tid):
    a_v = len(tid)
    vm = [0]
    t_v = 0

    for i in range(a_v - 1):
        try:
            h = tid[i   1] - tid[i]
            t_v  = aks[i] * h
            vm.append(t_v)
        except IndexError:
            break
    return(vm)


f = np.loadtxt("målinger.txt", float, skiprows=0)
acceleration = f[:, 0]
time = f[:, 1]

gravitational_acceleration = 9.81
mass = 0.5
k = 0.01

m_v = []
m_t = []
t_start = 0
t_end = 5
steps = 1000
length_steps = (t_end-t_start)/(steps-1)

velocity = np.zeros(steps)
time = np.zeros(steps)

for i in range(steps-1):
    velocity[i 1] = velocity[i]   length_steps * 
        (gravitational_acceleration - k * velocity[i]**2 / mass)
    time[i 1] = time[i]   length_steps

velocity_r = rektangelmetoden(acceleration, time)

plt.plot(time, velocity, color="b", label="Teoretisk modell")
plt.plot(time, velocity_r, color="r", label="målinger")
plt.xlabel("Time [s]")
plt.ylabel("Velocity [m/s]")
plt.title("Micro:Bit in parachute")
plt.grid()
plt.legend()
 

Я просто добавляю блок try/except, чтобы поймать ошибку индекса и выйти из for loop него .

Ответ №2:

Во-первых, вы используете производные, поэтому ваши данные об ускорении имеют на одну точку меньше, чем данные о скорости. Вы можете добавить значение 0 в начале (0-индекс) массива ускорения, например, aks.insert(0, 0) перед его повторением.

Теперь в коде, который вы выполняете вручную, есть много вещей, которые в numpy могут быть по сути однострочными. Вот мои предложения:

 from matplotlib import pyplot as plt
import numpy as np
from scipy.integrate import cumtrapz

# Calculate experimental velocity.
f = np.loadtxt("målinger.txt", float, skiprows=0)
acceleration_r = f[:, 0]
time_r = f[:, 1]
velocity_r = cumtrapz(acceleration_r, time_r, initial=0)

# Time array.
# I thought you'd like measured and theoretical times to automatically start and end at the same spots. 
t_start = time_r[0]
t_end = time_r[-1]
STEPS = 1000
time = np.linspace(t_start, t_end, STEPS, endpoint=True)
dt = time[1] - time[0]

# Calculate theoretical velocity.
g = 9.81
m = 0.5
k = 0.01
velocity = np.zeros(steps)
for i in range(steps-1):
    velocity[i 1] = velocity[i]   dt*(g - k*velocity[i]**2/m)

# Plot and compare both velocities.
fig, ax = plt.subplots()
fig.show()
ax.plot(time, velocity, color = "b", label = "Teoretisk modell")
ax.plot(time_r, velocity_r, color = "r", label = "målinger")
ax.set_xlabel("Time [s]")
ax.set_ylabel("Velocity [m/s]")
ax.set_title("Micro:Bit in parachute")
ax.grid()
ax.legend()
 

Обратите внимание, что я использую scipy.integrate.cumtrapz вместо вашей собственной функции ( rektangelmetoden ), но оба сталкиваются с проблемой потери одного очка. Scipy исправляет это с initial=0 помощью ключевого слова, которое добавляет начальное значение скорости и восстанавливает его до той же длины, что и массивы ускорения и времени.

Ответ №3:

Ваша ошибка заключается в том, что вы использовали time дважды, один раз прочитав файл и один раз создав его для эталонного решения, с несвязанной длиной. Однако после второго вы попытались снова использовать этот массив в контексте первого, что, как и следовало ожидать, привело к катастрофическим результатам.

Дайте временным массивам разные имена time_file и time_ref или то, что вы себе представляете.