两条曲线之间的二维插值(不等长的数组)
2D interpolation between two curves (arrays of inequal lengths)
我正在开发一个开源电池模型,我使用不同电池的数据表以在模型中使用它们。电池的温度特性如下所示:
当数据被采样为数值时,结果数组的长度不同:
我希望执行二维插值以确定给定容量和温度下的电池电压。
我很难找到插入此类数据的好方法。我确实意识到两个长度不等的数组之间的插值可能不是一个明确定义的问题,但我正在尝试寻找一种在这种情况下可以提供合理结果的解决方案。
我认为将数据正则化为网格可能会奏效,但我怀疑这对我来说不是一个很好的解决方案,因为曲线的长度和形状非常不均匀。如果您知道我的意思,我认为这可能会导致在曲线上相距较远且“彼此不对应”的两个点之间执行插值。
相反,我希望有一种解决方案可以“扩展”数据集的三角形部分。
如果您能提供任何可以帮助我找到解决方案的想法,我将不胜感激。
编辑 : 我会尽力澄清问题,如果我无法以清晰的方式表达,请见谅。
输入是数据表中的图表,这些图表被读入数值(假设 Excel/csv 用于存储,pandas 数据表用于 Python 代码)
输出是一个函数,对于定义域内的任何点(x=温度,y=容量),提供(z=电压)的内插值
我不完全理解第一个问题,但混淆可能来自于我不希望将图表作为输出并且我不推断任何数据。
我不知道共享数据的最佳方式是什么,我认为 170 行对 copy-paste 来说可能有点太多了。我也觉得没必要。
关键是我对图表上的曲线每 25 mAh 的容量进行了采样。由于电池在特定电压以下被切断,因此阵列具有不同的长度:60°C 曲线在 4200mAh 左右结束,而 -40°C 结束得更快,在 3600mAh 左右
EDIT2 N. Wouda :我希望允许共享链接,我在这里上传了 csv :https://transferxl.com/08jXjy5T1814kr
Pranav Hosangadi:在这种情况下,我会提出一个值错误
SciPy 有一个完全面向插值的模块,在 scipy.interpolate
. In the following code I use radial basis functions 处创建一个插值函数。恕我直言,这些结果比使用例如更平滑。 interp2d
直接获取,在数据集不太大的情况下获取还是比较经济的。缺点是径向基函数不需要考虑数据的比例 (min/max),尤其是在初始域之外。在使用插值之前你应该检查一下!
(另请参阅 ,了解不同插值函数的相对优势)
代码如下:
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)
值,这会导致下图:
这似乎是您要找的!
我正在开发一个开源电池模型,我使用不同电池的数据表以在模型中使用它们。电池的温度特性如下所示:
当数据被采样为数值时,结果数组的长度不同:
我希望执行二维插值以确定给定容量和温度下的电池电压。
我很难找到插入此类数据的好方法。我确实意识到两个长度不等的数组之间的插值可能不是一个明确定义的问题,但我正在尝试寻找一种在这种情况下可以提供合理结果的解决方案。
我认为将数据正则化为网格可能会奏效,但我怀疑这对我来说不是一个很好的解决方案,因为曲线的长度和形状非常不均匀。如果您知道我的意思,我认为这可能会导致在曲线上相距较远且“彼此不对应”的两个点之间执行插值。
相反,我希望有一种解决方案可以“扩展”数据集的三角形部分。
如果您能提供任何可以帮助我找到解决方案的想法,我将不胜感激。
编辑 : 我会尽力澄清问题,如果我无法以清晰的方式表达,请见谅。
输入是数据表中的图表,这些图表被读入数值(假设 Excel/csv 用于存储,pandas 数据表用于 Python 代码)
输出是一个函数,对于定义域内的任何点(x=温度,y=容量),提供(z=电压)的内插值
我不完全理解第一个问题,但混淆可能来自于我不希望将图表作为输出并且我不推断任何数据。
我不知道共享数据的最佳方式是什么,我认为 170 行对 copy-paste 来说可能有点太多了。我也觉得没必要。
关键是我对图表上的曲线每 25 mAh 的容量进行了采样。由于电池在特定电压以下被切断,因此阵列具有不同的长度:60°C 曲线在 4200mAh 左右结束,而 -40°C 结束得更快,在 3600mAh 左右
EDIT2 N. Wouda :我希望允许共享链接,我在这里上传了 csv :https://transferxl.com/08jXjy5T1814kr
Pranav Hosangadi:在这种情况下,我会提出一个值错误
SciPy 有一个完全面向插值的模块,在 scipy.interpolate
. In the following code I use radial basis functions 处创建一个插值函数。恕我直言,这些结果比使用例如更平滑。 interp2d
直接获取,在数据集不太大的情况下获取还是比较经济的。缺点是径向基函数不需要考虑数据的比例 (min/max),尤其是在初始域之外。在使用插值之前你应该检查一下!
(另请参阅
代码如下:
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)
值,这会导致下图:
这似乎是您要找的!