首页 > 解决方案 > 插值问题 - ValueError:所需数组的深度太小(Python,numpy)

问题描述

我是 Python 的初学者,我一直在设计一个程序,它读取关于 2 个恒星属性(bv_colour_indexluminosity)的真实 csv 数据,然后在点之间线性插值以计算 bv_colour_index 任意值的亮度。我没有以任何方式存储输出,我的测试类实例也没有循环通过 bv_colour_index 的小值。

问题是,在 OOP 遇到一些麻烦(我才刚刚开始掌握)之后,插值不能按预期工作,而是抛出这个:

ValueError:所需数组的对象深度太小

作为参考,这是我的代码。

import csv
import numpy as np
from random import *


class Star:

    sun_luminosity = 3.828e+26  # W
    sun_effective_temperature = 5.772e+3  # K

    @staticmethod
    def csv_bv_colour_index_extractor():
        with open('HR_Data.csv') as hr:
            hr_read = csv.reader(hr)
            bv_index_list = []

            for column in hr_read:
                bv_index_list.append(float(column[0]))
        return bv_index_list

    @staticmethod
    def csv_luminosity_extractor():
        with open('HR_Data.csv') as hr:
            hr_read = csv.reader(hr)
            luminosity_list = []

            for column in hr_read:
                luminosity_list.append(float(column[1]))
        return luminosity_list

    def __init__(self, bv_colour_index, xp=csv_bv_colour_index_extractor, fp=csv_luminosity_extractor):
        self.bv_colour_index = bv_colour_index
        self.xp = xp
        self.fp = fp

    def calculate_luminosity(self):

        luminosity_ratio = np.interp(self.bv_colour_index, self.xp, self.fp)
        randomization_range = randint(-50, 50) / 1000
        luminosity_ratio = luminosity_ratio(1 + randomization_range)
        luminosity = luminosity_ratio * Star.sun_luminosity

        return luminosity


star = Star(2)
print(star.calculate_luminosity())

如何解决这个问题?据我所见,没有很多文档可以提供帮助。

如果我在这个程序上使用 OOP 时使用了任何非 pythonian/明显错误的技术,如果你能指出它们,我会很高兴。提前谢谢了!

标签: pythonnumpyoopinterpolation

解决方案


OOP 对于这类任务可能有点矫枉过正,除非你想编写一个更大的软件来从它的结构中受益。这是我对如何做到这一点的看法:

import csv
import numpy as np
import random as rand

class Star:
  # Constants as uppercase variables (class attributes)
  SUN_LUMINOSITY = 3.828e+26  # W
  SUN_EFFECTIVE_TEMPERATURE = 5.772e+3  # K

  # Define __init__ (constructor) right after the constants
  def __init__(self, file_path):
    self.file_path = file_path
    self.data = self.__load_data()
    self.randomization_range = rand.randint(-50, 50) / 1000

  # __ in front of method name indicates that it is only to be used 
  # inside of the class (encapsulation)
  def __load_data(self):
    with open(self.file_path) as csv_file:
      reader = csv.reader(csv_file)
      next(reader)  # skip header in csv file
      data = list(reader)
    return data

  def __get_and_transform_column(self, column_index):
    return [float(row[column_index]) for row in self.data]

  # @property decorator: method behaves similar to a class attribute
  # (a getter of sorts). 
  @property
  def luminosity(self):
    bv_colour_index = self.__get_and_transform_column(0)
    luminosity_values = self.__get_and_transform_column(1)
    luminosity_ratio = np.interp(self.data, 
                                 xp=bv_colour_index, 
                                 fp=luminosity_values)
    luminosity_ratio *= (1 + self.randomization_range)
    return luminosity_ratio * self.SUN_LUMINOSITY

# Initialize class with the file path
star = Star('HR_Data.csv')

# Get interpolated luminosity values
print(star.luminosity)

推荐阅读