问题
I have tried to fit data on the high and low-temperature regime of the thermal profile, but I couldn't fit properly. According to the experiment report, there should be 3 to 4 measurement points on each level however I couldn't manage it till now due to always there are some points could be outside of thermal profile curve and ruin everything. I checked this post about optimize.curve_fit()
, and I'm unsure it can help in my case to optimize it. As it is illustrated in the last picture, measurement points in each high or low regime should be fit in each dwell-time next to each other:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import itertools
import copy
from sklearn import preprocessing
# load dataset
data_train = pd.read_csv("data.csv", header=None)
Temp = data_train.iloc[:, 2::3]
print(Temp)
"""
stack(): transform your (sliced) dataframe to a series with index (row, col)
reset_index(): reset the double-level index above to level_0 (row), level_1 (col).
"""
def preprocess(data):
for i in range(data.shape[0] // 480):
if 150 in data.iloc[i*480:(i+1)*480].to_numpy() and -40 in data.iloc[i*480:(i+1)*480].to_numpy():
if 150 in data.iloc[(i-1)*480:i*480].to_numpy():
data.iloc[i*480:(i+1)*480] = -40
else:
data.iloc[i*480:(i+1)*480] = 150
return data
Temp = data_train.iloc[:, 2::3][100:200].stack().reset_index().reset_index()
Temp.columns = ['idx', 'level_0', 'level_1', 'Temperature']
Temp.Temperature = preprocess(Temp.Temperature)
temperature_data = copy.deepcopy(Temp)
fig, ax = plt.subplots(1,1, figsize=(16,10))
Temp.plot('level_0', 'Temperature', ax=ax, kind='scatter', c='level_0', colormap='prism', colorbar=False, legend=True)
ax.set_title('Temperature data distribution over cycles ', fontweight='bold', fontsize=18)
ax.set_xlabel('Cycles', fontsize=16)
ax.set_ylabel('Temperature', fontsize=16)
ax.tick_params(axis='both', which='major', labelsize=14)
#ax.tick_params(axis='both', which='minor', labelsize=10)
plt.show()
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
### A continuous function that somewhat fits the data
### but definitively gets the period and levels.
### The ramp is less well defined
def fit_func( t, low, high, period, s, delta):
return ( high + low ) / 2. + ( high - low )/2. * np.tanh( s * np.sin( 2 * np.pi * ( t - delta ) / period ) )
time1List = np.arange( data_train.shape[0] )
time2List = np.linspace( 0, data_train.shape[0], 7213*20 )
tempList = np.fromiter( ( np.mean(temperature_data.Temperature[temperature_data.level_0 == t]) for t in time1List ), np.float )
sol, err = curve_fit( fit_func, time1List, tempList, [ -40, 150, 1, 10, 0 ] )
print(sol)
fittedLow, fittedHigh, fittedPeriod, fittedS, fittedOff = sol
# sol = -40, fittedHigh, fittedPeriod, fittedS, fittedOff
realHigh = fit_func( 1/4 * fittedPeriod, *sol)
realLow = fit_func( 3/4 * fittedPeriod, *sol)
print("high, low : ", [ realHigh, realLow ])
print("apprx ramp: ", fittedPeriod/( 2 * np.pi * fittedS ) * 2)
realAmp = realHigh - realLow
topX, topY = zip( *[ [ t, d ] for t, d in zip( time1List, tempList ) if ( ( d > realHigh - 0.05 * realAmp ) ) ] )
botX, botY = zip( *[ [ t, d ] for t, d in zip( time1List, tempList ) if ( ( d < realLow + 0.05 * realAmp ) ) ] )
fig = plt.figure(figsize=(20, 15))
ax = fig.add_subplot( 2, 1, 1 )
bx = fig.add_subplot( 2, 1, 2 )
ax.plot( time1List, tempList, marker='x', linestyle='', zorder=100 )
ax.plot( time2List, fit_func( time2List, *sol ), zorder=0 )
ax.set_title('Fitting whole MPs on standrad thermal profile ', fontweight='bold', fontsize=25)
ax.set_xlabel('cycles', fontsize=20)
ax.set_ylabel('Thermal regime', fontsize=20)
bx.plot( time1List, tempList, marker='x', linestyle='' )
bx.plot( time2List, fit_func( time2List, *sol ) )
bx.plot( topX, topY, linestyle='', marker='o', markersize=10, fillstyle='none', color='#00FFAA')
bx.plot( botX, botY, linestyle='', marker='o', markersize=10, fillstyle='none', color='#80DD00')
bx.set_title('Fitting part of MPs on standrad thermal profile ', fontweight='bold', fontsize=25)
bx.set_xlabel('cycles', fontsize=20)
bx.set_ylabel('Thermal regime', fontsize=20)
bx.set_xlim( [ 110, 120 ] )
plt.show()
Any suggestion to fix correctly fitting measurement points on dwell-time in thermal profile ?
来源:https://stackoverflow.com/questions/57741001/how-can-optmize-fitting-data-on-thermal-profile-properly