两条曲线之间的二维插值(长度不等的数组)

Posted

技术标签:

【中文标题】两条曲线之间的二维插值(长度不等的数组)【英文标题】:2D interpolation between two curves (arrays of inequal lengths) 【发布时间】:2021-06-01 14:01:44 【问题描述】:

我正在开发一个开源电池模型,并使用不同电池的数据表在模型中使用它们。电池的温度特性如下所示:

当数据被采样为数值时,结果数组的长度不同:

我希望执行 2D 插值,以确定给定容量和温度下的电池电压。

我很难找到一种插入此类数据的好方法。我确实意识到两个长度不等的数组之间的插值可能不是一个定义明确的问题,但我正在尝试寻找一种解决方案,在这种情况下可以提供合理的结果。

我认为将数据规范化为网格可能有效,但我怀疑这不是一个很好的解决方案,因为曲线的长度和形状有多不均匀。如果您知道我的意思,我认为这可能会导致在曲线上相距较远且“彼此不对应”的两个点之间执行插值。

相反,我希望有一种解决方案可以“扩展”数据集的三角形部分。

如果您能提供任何可以帮助我找到解决方案的想法,我将非常感激。

编辑:我会尽量澄清问题,如果我无法清楚地表达出来,请见谅。

输入是数据表中的图表,这些图表被读入数值(比如说 Excel/csv 用于存储,pandas 数据表用于 Python 代码)

输出是一个函数,它为定义域 (x=Temperature, y=Capacity) 内的任何点提供 (z=Voltage) 的插值

我不完全理解第一个问题,但混淆可能来自于我不希望将图表作为输出并且我不推断任何数据这一事实。

我不知道哪种方式是共享数据的最佳方式,我认为 170 行可能有点过多,无法复制粘贴。我也觉得没必要。

关键是我在图表上对每 25 mAh 容量的曲线进行了采样。由于电池在一定电压以下被切断,因此阵列的长度不同:60°C曲线结束在4200mAh左右,而-40°C曲线结束得更快,在3600mAh左右

EDIT2 N. Wouda:我希望允许分享链接,我在这里上传了 csv:https://transferxl.com/08jXjy5T1814kr

Pranav Hosangadi:在这种情况下,我会提出一个值错误

【问题讨论】:

如果您没有对整个范围进行采样,那么如何在整个范围内绘制图表?通过外推?如果是这样,而且这些图看起来很合理,为什么规则网格(比如样条线)还不够? 另外,请将数据发布为可复制粘贴的代码,最好通过复制粘贴加载到数据框中。 并且,发布可复制粘贴的代码以根据数据创建图。 或者我不明白,您正在尝试根据您不完整的数据创建这些您知道正确的图表?请将问题定义为输入作为输出。 您能否至少提供数据集(作为 csv/excel)? 【参考方案1】:

SciPy 有一个完全面向插值的模块,位于 scipy.interpolate。在下面的代码中,我使用radial basis functions 创建一个插值函数。恕我直言,这些结果比使用例如更平滑的结果。直接interp2d,在数据集不太大的情况下获取它们是相当经济的。缺点是径向基函数不需要考虑数据的比例(最小值/最大值),尤其是在初始域之外。你应该在使用插值之前检查一下!

(另请参阅this answer,了解不同插值函数的相对优势)

代码如下:

import re

import numpy as np
import pandas as pd
from scipy import interpolate
    

def interp(df: pd.DataFrame):
    temp = []
    cap = []
    voltage = []

    for col in df.columns:
        if col.startswith("Voltage"):
            temp.extend([_col_to_temp(col)] * len(df.Capacity))
            cap.extend(df.Capacity)
            voltage.extend(df[col])

    x = np.array(temp)
    y = np.array(cap)
    z = np.array(voltage)

    isna = pd.isna(z)

    return interpolate.Rbf(x[~isna], y[~isna], z[~isna])


def _col_to_temp(col: str) -> float:
    # Gets temperature from column name 
    res = re.findall(r'[+-]?\d+', col)
    return float(res[0])


df = pd.read_csv("Molicel_Temperature.csv")
f = interp(df)

希望它相当简单。 f 是插值函数,采用温度和容量参数,例如f(50, 2000),返回插值电压。例如,这会导致下面的图表显示 (temp, capacity) 的不同值:

这似乎就是你要找的东西!

【讨论】:

以上是关于两条曲线之间的二维插值(长度不等的数组)的主要内容,如果未能解决你的问题,请参考以下文章

插值二维点数组

mathematic或者其它数学软件求二维曲线长度

Python - 使用样条线插值二维点云

二维数组名不能赋值给二级指针- -

气象 python 二维线性插值

两条线的交点 - 数值分析