相同Python代码、机器与数据运行结果不一致的技术求助
曲线拟合结果不一致问题求助
我编写了一段基于numpy和math库的Python代码,用于读取文本文件中的多列数据并执行曲线拟合。首次运行该代码时,机器同时在运行另一段Python分析代码,得到了一组结果;再次单独运行时,结果却差异巨大。为验证结果正确性,我在MATLAB中重复计算,成功复现了Python第二次运行的结果。恳请各位提供导致该问题的原因线索,如需测试我可私下分享数据与代码。
代码实现
import pandas as pd import numpy as np import typing as tp import math as mt import matplotlib.pyplot as plt def curveFitting(energyData: tp.Dict[float, float], order: int) -> None: pesDataFrame = pd.DataFrame(columns = ["Distance", "Energy"]) for key in energyData: pesDataFrame.loc[len(pesDataFrame)] = [key, energyData[key]] # Create a DataFrame to drop all energy values above 0 cm-1 pesDataFrame = pesDataFrame[pesDataFrame["Energy"] <= 0] # Drop all energies greater than 0 cm-1 # pesDataFrame = pesDataFrame[pesDataFrame["Distance"] > 1.4] distances = pesDataFrame["Distance"].to_numpy() energies = pesDataFrame["Energy"].to_numpy() rEquilibrium = distances[energies.argmin()] distances = np.delete(distances, energies.argmin()) energies = np.delete(energies, energies.argmin()) xRvalues = np.zeros(distances.size) print(rEquilibrium) for index, value in enumerate(distances): xRvalues[index] = (pow(value, 3) - pow(rEquilibrium, 3)) / (pow(value, 3) + pow(rEquilibrium, 3)) # Calculate x(r) values according to Eq 14 xMatrix = np.zeros((distances.size, order+1)) for row, value in enumerate(xRvalues): for ordercount in range(0, order+1): xMatrix[row][ordercount] = pow(value, ordercount) # Calculate xMatrix according to Eq 19 print(xMatrix.shape) # term1 = np.zeros(distances.size) term2 = np.zeros(distances.size) rescaledEnergy = np.zeros(distances.size) minEnergy = energies[energies.argmin()] dissocEnergy = 0 - minEnergy # Calculate dissociation energy as difference between minimum and zero energy. for index, value in enumerate(energies): rescaledEnergy[index] = (value - minEnergy) / dissocEnergy for index, value in enumerate(distances): # term1[index] = np.emath.log(1 - mt.sqrt(rescaledEnergy[index])) # Eq 11 term2[index] = np.emath.log(1 - mt.sqrt(rescaledEnergy[index])) # Eq 12 # term1[index] = term1[index] / (rEquilibrium - value) term2[index] = term2[index] / (rEquilibrium - value) # First calculate beta from Eq 11 beta, _, _, _ = np.linalg.lstsq(xMatrix, term2, rcond = None) print(beta.shape) calculateBetas = np.dot(xMatrix, beta) errorVector = term2 - calculateBetas print(np.linalg.norm(errorVector)) # calculateBetas = np.zeros(distances.shape) # for row in range(xMatrix.shape[0]): # calculateBetas[row] = np.dot(xMatrix[row], beta) calculateEnergies1 = np.zeros(distances.shape) # errorVector = np.zeros(distances.shape) for index, value in enumerate(distances): distance = value - rEquilibrium betaterm = mt.exp(-1*calculateBetas[index]*distance) nextterm = pow(1-betaterm, 2) * dissocEnergy calculateEnergies1[index] = nextterm + minEnergy # errorVector[index] = energies[index] - calculateEnergies1[index] error = np.linalg.norm(errorVector) plt.plot(distances, energies, "-r", label = "UCCSD(T) Energy") plt.plot(distances, calculateEnergies1, "-b", label = "Fitted Energies") plt.title("Fitting Order : {} and Error : {:10.5f}".format(order, error)) plt.xlabel("Interatomic Distance") plt.ylabel("Energy (cm-1)") plt.legend() plt.savefig("uccsdt_fitting_order_{}.png".format(order), dpi = 600) with open("energies_neutral_631g.dat") as energyFile: uhfEnergy = {} uccsdEnergy = {} uccsdtEnergy = {} for line in energyFile: line = line.split() dist = float(line[0]) # Distance uhf = float(line[1]) # UHF Energy uccsd = float(line[2]) # UCCSD Energy uccsdt = float(line[3]) # UCCSD Energy with UCCSD(T) corrections uhfEnergy[dist] = uhf uccsdEnergy[dist] = uccsd uccsdtEnergy[dist] = uccsdt for order in range(0,20): curveFitting(energyData = uccsdtEnergy, order = order) plt.clf()
可能的原因线索
- 字典遍历顺序不稳定:Python 3.7之前的字典不保证遍历顺序固定,你通过
for key in energyData生成DataFrame时,不同运行场景下(比如系统负载波动)可能导致DataFrame的行顺序变化。后续删除能量最小值对应的索引、构建拟合矩阵等步骤都会受此影响,最终引发拟合结果的巨大差异。 - 资源竞争引发计算异常:首次运行时机器同时执行其他分析代码,可能出现内存不足、CPU调度异常,导致numpy的最小二乘计算(
np.linalg.lstsq)出现精度丢失或计算偏差,比如浮点数运算的中间结果被干扰。 - 拟合逻辑对数据顺序敏感:代码中涉及多次幂运算、对数运算、除法操作,这些步骤对输入数据的顺序和微小数值变化高度敏感。一旦数据顺序因字典遍历改变,后续所有计算都会产生连锁反应,最终导致结果偏差显著。
内容的提问来源于stack exchange,提问作者Hemanth Haridas
相关产品推荐
相关产品推荐

