Files
controller-data-analysis/ana_func.py
T
2023-01-03 16:57:08 +08:00

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