122 lines
5.2 KiB
Python
122 lines
5.2 KiB
Python
import random, math, time
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
from scipy import signal
|
|
import pandas as pd
|
|
|
|
class dataAnalyticFunc():
|
|
|
|
def __init__(self, x_data, y_data) ->None:
|
|
if len(x_data)!=len(y_data):
|
|
print('Scale of x_data and y_data are different.')
|
|
return None
|
|
self._raw_data = pd.DataFrame({'x_data':x_data,'y_data':y_data})
|
|
# print(self._raw_data['y_data'].tolist())
|
|
|
|
def trigger_point(self, value_data, key_data, trigger, order = 1, drop = 1):
|
|
if value_data not in list(self._raw_data) or key_data not in list(self._raw_data):
|
|
print( 'There is no '+ str(value_data) + 'in datafram. ')
|
|
return False
|
|
# print(self._raw_data[value_data].head(10))
|
|
last_row, last_key = [],False
|
|
for i,row in self._raw_data.sort_values(key_data)[::order].iterrows():
|
|
# print(row[key_data])
|
|
if row[value_data]*drop <= trigger*drop:
|
|
print (i,type(row))
|
|
last_row ,last_key = row,True
|
|
print(last_row[key_data])
|
|
break
|
|
# print(last_row==False)
|
|
if last_key ==False:
|
|
print('No data meet the criteria.')
|
|
return False
|
|
|
|
# print(last_key)
|
|
# return [int(self._raw_data[key_data][last_key]), int(self._raw_data[value_data][last_key])]
|
|
return [last_row[key_data],last_row[value_data]]
|
|
|
|
def histogram_find_peak(self, bins =100): #, plot =True):
|
|
# if bins == 0:
|
|
# bins = 100
|
|
# bins = round(len(self._raw_data)/10)
|
|
arr_list = self._raw_data['y_data'].tolist()
|
|
self._raw_data['hist_list'] = pd.cut(self._raw_data['y_data'], bins)
|
|
|
|
hist_list = self._raw_data['hist_list'].value_counts(sort=False).tolist()
|
|
cut_bins = self._raw_data['hist_list'].value_counts(sort=False).keys()
|
|
# print(cut_bins[0])
|
|
# hist_list = [len([j for j in self._raw_data_y if j>=hist_range[i] and j<hist_range[i+1]]) for i in range(len(hist_range)-1)]
|
|
peek_temp_list,_ = signal.find_peaks(list(hist_list))
|
|
peek_temp_list = list(peek_temp_list)
|
|
if np.sign(np.diff(hist_list))[0] < 0:
|
|
peek_temp_list = [0] + peek_temp_list
|
|
if np.sign(np.diff(hist_list))[-1] > 0:
|
|
peek_temp_list = peek_temp_list+[len(hist_list)-1]
|
|
peek_list = [i for i in peek_temp_list if hist_list[i] >= len(self._raw_data)/bins*3]
|
|
print(peek_list)
|
|
results_half = signal.peak_widths(hist_list, peek_list, rel_height=0.8)
|
|
# print(results_half)
|
|
peak_range = [ pd.Interval(cut_bins[round(results_half[2][i])].left, cut_bins[round(results_half[3][i])].right) for i in range(len(results_half[2]))]
|
|
# print(peak_range)
|
|
peak_wid = [ np.mean([ j for j in arr_list if j in i]) for i in peak_range ]
|
|
data_list = {'ground':round(min(peak_wid)), 'ceiling':round(max(peak_wid)) }
|
|
# print(peek_list)
|
|
# print("peak_wid = "+str(peak_wid))
|
|
print(data_list)
|
|
|
|
return data_list, cut_bins
|
|
|
|
def cal_slop_array(self, window = 10):
|
|
# print(self._raw_data)
|
|
print('window')
|
|
if window*2+1 >= len(self._raw_data):
|
|
print('Scale of data are smaller than window.')
|
|
return False
|
|
slop_a = [0]*window
|
|
for i in range(len(self._raw_data)-window*2):
|
|
# print(list(self._raw_data['x_data'][i:i+window*2+1]))
|
|
s,_ = np.polyfit(list(self._raw_data['x_data'][i:i+window*2+1]), list(self._raw_data['y_data'][i:i+window*2+1]), 1)
|
|
# time.sleep(3)
|
|
# print(s)
|
|
slop_a.append(s)
|
|
slop_a = slop_a+[0]* window
|
|
self._raw_data['1D'] = slop_a
|
|
|
|
print(list(self._raw_data))
|
|
return slop_a
|
|
|
|
def guess_func(self,value_name='y_data', window = 10):
|
|
win = window
|
|
X = np.array([[math.pow(i,j) for j in range(4)] for i in np.linspace(-1*win,win,2*win+1)])
|
|
J = np.linalg.inv(X.T.dot(X)).dot(X.T)
|
|
slop_list = []
|
|
for i in range(len(self._raw_data[value_name][win:-1*win])):
|
|
slop_list.append(J.dot(np.array(self._raw_data[value_name][i:i+2*win+1])).tolist()[1])
|
|
slop_list = [slop_list[0]]*win +slop_list+ [slop_list[-1]]*win
|
|
return slop_list
|
|
|
|
def simple_slop(self,value_name='y_data',key_name='x_data'):
|
|
df = self._raw_data.sort_values(key_name)
|
|
slop_list = []
|
|
for i in range(len(df)-1):
|
|
df[value_name].iloc[i+1]-df[value_name].iloc[i]
|
|
|
|
def integral_func(self, int_value_name, int_key_name, sort=True ):
|
|
df = self._raw_data.sort_values(int_key_name) if sort else self._raw_data
|
|
temp_value_sum = 0
|
|
last_key = df[int_key_name].iloc[0]
|
|
temp_key_num = 0
|
|
integral_value = 0
|
|
for i in range(len(df)):
|
|
row = df.iloc[i]
|
|
if last_key == row[int_key_name] :
|
|
temp_value_sum += row[int_value_name]
|
|
temp_key_num += 1
|
|
else:
|
|
integral_value += (row[int_key_name]-last_key) * temp_value_sum/temp_key_num
|
|
last_key = row[int_key_name]
|
|
temp_value_sum = row[int_value_name]
|
|
temp_key_num = 1
|
|
return integral_value
|
|
|