首页 > 编程问答 >无法获取 curve_fit 的正确数据类型。例如:不可散列、具有序列的数组等

无法获取 curve_fit 的正确数据类型。例如:不可散列、具有序列的数组等

时间:2024-07-28 10:14:50浏览次数:12  
标签:python numpy curve-fitting dtype

我正在使用一个脚本来使用 curve_fit 分析 nmr 弛豫率,并从外部文件引入输入和输出值。当我实际尝试运行 curve_fit 时,我遇到了许多关于这些数据类型的错误消息,例如数据处于不可散列的类型、错误地将数组转换为序列、数据形状不同等。我修改了我的脚本确保它们具有相同的数据类型(对象字符串)和形状(36,),但我仍然无法在没有收到错误消息的情况下运行它。我感觉有一个非常简单的修复,我只是错过了一些东西,但我似乎无法弄清楚是什么,任何帮助将不胜感激!

这是当前的完整脚本:

import math 
import numpy as np
from numpy import *
import scipy
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import matplotlib.cm as cm
import nmrglue as ng
import sys
from mpl_toolkits.mplot3d import Axes3D
from pathlib import Path
import csv
import pandas as pd

def exp(x, a, b, c):
    d=1/b 
    return a+c*np.exp(-b*x) 

out=open((f'/Users/haileyrude/Dropbox/OkunoNMR/1/output.txt'), 'w')

List_area=[]
List_inten=[]

with open(str(f'Okuno Lab Python Work/Okuno Test 1/tau.list'), 'r') as d:
    reader = csv.reader(d)
    prepretauList = list(reader)
    pretauList = np.array(prepretauList)
    tauList = pretauList.astype(str)

dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test036.ft1')))#ZY

udic = ng.pipe.guess_udic(dic,data)
uc = ng.fileiobase.uc_from_udic(udic)
ppm_1H = uc.ppm_scale()
uc0 = ng.pipe.make_uc(dic,data,dim=0)
ub=uc0("6.5ppm")
lb=uc0("9.5ppm")

ppm = ppm_1H[lb:ub]
inten = data[lb:ub]
maxvalue=max(inten.real)
pt=np.where(data.real==maxvalue)
intensity=data[pt]
maxpt=uc0.ppm(pt[0])
    
display(uc0.ppm(pt[0]))
off=0
count=0
for i in range(1, len(tauList)+1, 1):
    
    off=off+500
    count=count+1
    try:
        dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test00{str(i)}.ft1')))#ZY
    except IOError:
        dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test0{str(i)}.ft1')))#ZY

    #print(dic,data)
    #define intergration area for the methyl, include some baseline
    ppm = ppm_1H[lb:ub]
    inten = data[lb:ub]
    intensity=data[pt]
    
    #intergrate
    area=inten.sum()
    List_area.append(float(area.real)) 
    List_inten.append(intensity.real)

    colors = cm.gist_heat(np.linspace(0, 1, len(tauList)+1))
    plt.xlim([6.5, 9.5])
    plt.plot(ppm, inten.real, color=colors[count]) 


prex=array(tauList, dtype="object")
arx=prex.astype(str)
x=prex.flatten()

prey=array(List_inten, dtype="object")
ary=prey.astype(str)
y=ary.flatten()

popt, pcov = curve_fit(exp, x, y)
#get the errors
errors=np.sqrt(pcov.diagonal())
print ('rate', popt[1], '+/-', errors[1] )   
print(out,'rate', popt[1], '+/-', errors[1]) 
    

#print 'Relax rate:', popt[1], '+/-', float(errors[1])


rate_fig = plt.figure(1)
plt.plot(tauList, List_inten, marker='o', markersize=10, linestyle='None')
plt.plot(xaxis, exp(xaxis, *popt), marker='None', linestyle='-', linewidth=2, color='r')
plt.show()

当我运行时这个确切的脚本我收到错误消息:“unhashable type:'numpy.ndarray'”,但是每当我尝试其他脚本时,我都会收到关于 curve_fit 不兼容数据类型的类似错误消息

此外,在尝试理解的根源时我的问题我运行了这个单元格:

print(x)
print(len(x))
print(x.shape)
print(x.dtype)

print(y)
print(len(y))
print(y.shape)
print(y.dtype)

并收到了这个输出:

x = ['0.001000' '0.001500' '0.002000' '0.002500' '0.003000' '0.004000' '0.005000' '0.007500' '0.010000' '0.012500' '0.015000' '0.017500' '0.020000' '0.022500' '0.025000' '0.027500' '0.030000' '0.035000' '0.050000' '0.075000' '0.100000' '0.125000' '0.150000' '0.175000' '0.250000' '0.500000' '0.750000' '1.000000' '1.250000' '1.500000' '1.750000' '2.000000' '2.500000' '3.000000' '3.500000' '5.000000']

len(x) = 36

x.shape = (36,)

x dtype = 对象

y = ['-157341216.0''-156514192.0''-156109792.0''-155292736.0' '-155541808.0' '-154359088.0' '-153406112.0' '-152017536.0' '-150163360.0' '-148821312.0' '-147121408.0' '-145200544.0' '-143513360.0' '-142319280.0' '-140684704.0' '-139887536.0' '-138132720.0' '-135468448.0' '-127346128.0' '-114155104.0' '-101980152.0''-90303376.0''-78995040.0''-68271560.0''-38386176.0' “38851676.0”“89095032.0”“121053536.0”“142517744.0”“155447904.0” '163979280.0' '168583824.0' '174455648.0' '176974160.0' '177651056.0' '178662960.0']

len(y) = 36

y.shape = (36,)

y dtype = <U12

同样,我想有一个非常简单的解决方案,但不幸的是我可以好像没找到谢谢你!!


问题在于你的 x y 数组包含的是字符串而不是数字。你需要将它们转换为数字以便 curve_fit 能够正确处理它们。

你可以使用 np.astype(float) 一次性将 tauList List_inten 转换为浮点数数组,如下所示:

x = np.array(tauList, dtype=float).flatten()
y = np.array(List_inten, dtype=float).flatten()

这将创建 x y 的浮点数版本,你就可以将它们传递给 curve_fit 函数。

以下是修改后的代码:

import math 
import numpy as np
from numpy import *
import scipy
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import matplotlib.cm as cm
import nmrglue as ng
import sys
from mpl_toolkits.mplot3d import Axes3D
from pathlib import Path
import csv
import pandas as pd

def exp(x, a, b, c):
    d=1/b 
    return a+c*np.exp(-b*x) 

out=open((f'/Users/haileyrude/Dropbox/OkunoNMR/1/output.txt'), 'w')

List_area=[]
List_inten=[]

with open(str(f'Okuno Lab Python Work/Okuno Test 1/tau.list'), 'r') as d:
    reader = csv.reader(d)
    tauList = np.array(reader, dtype=float).flatten()  # 将 tauList 转换为浮点数数组

dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test036.ft1')))#ZY

udic = ng.pipe.guess_udic(dic,data)
uc = ng.fileiobase.uc_from_udic(udic)
ppm_1H = uc.ppm_scale()
uc0 = ng.pipe.make_uc(dic,data,dim=0)
ub=uc0("6.5ppm")
lb=uc0("9.5ppm")

ppm = ppm_1H[lb:ub]
inten = data[lb:ub]
maxvalue=max(inten.real)
pt=np.where(data.real==maxvalue)
intensity=data[pt]
maxpt=uc0.ppm(pt[0])

display(uc0.ppm(pt[0]))
off=0
count=0
for i in range(1, len(tauList)+1, 1):

    off=off+500
    count=count+1
    try:
        dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test00{str(i)}.ft1')))#ZY
    except IOError:
        dic,data = ng.pipe.read(str(Path(f'/Users/haileyrude/Dropbox/OkunoNMR/1/ft/test0{str(i)}.ft1')))#ZY

    #print(dic,data)
    #define intergration area for the methyl, include some baseline
    ppm = ppm_1H[lb:ub]
    inten = data[lb:ub]
    intensity=data[pt]

    #intergrate
    area=inten.sum()
    List_area.append(float(area.real)) 
    List_inten.append(intensity.real)

    colors = cm.gist_heat(np.linspace(0, 1, len(tauList)+1))
    plt.xlim([6.5, 9.5])
    plt.plot(ppm, inten.real, color=colors[count]) 


y = np.array(List_inten, dtype=float).flatten()  # 将 List_inten 转换为浮点数数组

popt, pcov = curve_fit(exp, x, y)
#get the errors
errors=np.sqrt(pcov.diagonal())
print ('rate', popt[1], '+/-', errors[1] )   
print(out,'rate', popt[1], '+/-', errors[1]) 


#print 'Relax rate:', popt[1], '+/-', float(errors[1])


rate_fig = plt.figure(1)
plt.plot(tauList, List_inten, marker='o', markersize=10, linestyle='None')
plt.plot(xaxis, exp(xaxis, *popt), marker='None', linestyle='-', linewidth=2, color='r')
plt.show()

这段修改后的代码应该能够解决你在 curve_fit 函数中遇到的数据类型错误。

标签:python,numpy,curve-fitting,dtype
From: 78802767

相关文章