Добавил:
hiiamfool
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:1 / main
.pyimport os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
def calculate_partitioned_entropy(time_col, signal_col, k=6, Nt=4):
Y = signal_col.reshape(-1, 1)
N = len(Y)
h_step = np.mean(np.diff(time_col))
tau_end = time_col[-1] * 0.2
# 1. Кластеризация фазового пространства
kmeans = KMeans(n_clusters=k, n_init=10, random_state=42)
idx = kmeans.fit_predict(Y)
# Вероятности нахождения в кластерах (вес кластера)
_, counts = np.unique(idx, return_counts=True)
rho = counts / N
# Инициализация массивов для расчета
tauspan = np.arange(h_step, tau_end, h_step)
NL = N - int(np.ceil(tau_end / h_step))
tL = np.zeros(NL) # Время первого выхода из кластера
hp = np.zeros(len(tauspan))
for j, tau in enumerate(tauspan):
ns = int(np.round(tau / h_step))
if ns == 0: continue
if N - ns <= 0: break
idxold = idx[:N-ns]
idxnew = idx[ns:]
limit_len = min(len(idxold), NL)
# Определение времени покидания исходного кластера (tL)
cngs = (idxold[:limit_len] != idxnew[:limit_len])
idleave = (tL[:limit_len] == 0) & cngs
tL[:limit_len][idleave] = tau
# Вычисление условной энтропии
S = 0
for i in range(k):
mask_i = (idxold == i)
if not np.any(mask_i): continue
transitions = idxnew[mask_i]
_, target_counts = np.unique(transitions, return_counts=True)
p_cond = target_counts / np.sum(target_counts)
# Взвешенная сумма по формуле Шеннона: -rho_i * sum(p * ln p)
rho_i = rho[i] if i < len(rho) else 0
hi = -rho_i * np.sum(p_cond * np.log(p_cond))
S += hi
hp[j] = S
# Аппроксимация наклона
# tau0 - время, за которое все точки успевают покинуть начальные кластеры
tau0 = np.max(tL) if np.max(tL) > 0 else h_step
# Выбор линейного участка [tau0, Nt * tau0] для оценки производной
indices_fit = np.where((tauspan >= tau0) & (tauspan <= Nt * tau0))[0]
# Fallback для слишком коротких диапазонов
if len(indices_fit) < 2:
indices_fit = np.where(tauspan >= tau0)[0]
if len(indices_fit) < 2:
indices_fit = range(len(tauspan)//2, len(tauspan))
ts_fit = tauspan[indices_fit]
hp_fit = hp[indices_fit]
slope, intercept = np.polyfit(ts_fit, hp_fit, 1)
return tauspan, hp, ts_fit, slope, intercept, slope
def process_files(files):
for filename in files:
if not os.path.exists(filename):
print(f"Файл {filename} не найден.")
continue
print(f"Обработка файла: {filename}...")
try:
# Чтение и очистка данных
df = pd.read_excel(filename, header=None, usecols=[0, 2])
df.columns = ['Time', 'Signal']
df = df.dropna()
time_data = df['Time'].values
signal_data = df['Signal'].values
except Exception as e:
print(f"Ошибка при чтении: {e}")
continue
# Расчет энтропии
taus, hp, t_fit, slope, intercept, val_hks = calculate_partitioned_entropy(
time_data, signal_data, k=8, Nt=5
)
# Визуализация результатов
plt.figure(figsize=(10, 6))
plt.plot(taus, hp, label=r'$h_p(\tau)$', color='blue', linewidth=2)
plt.plot(t_fit, slope * t_fit + intercept, 'r--', linewidth=2, label='Аппроксимация')
plt.title(f'Файл: {filename}. Оценка $h_{{KS}} \\approx {val_hks:.4f}$', fontsize=14)
plt.xlabel(r'$\tau$ (сек)', fontsize=12)
plt.ylabel(r'$h_p(\tau)$', fontsize=12)
plt.legend()
plt.grid(True)
output_name = f'F{filename.replace(".xlsx", "")}.png'
plt.savefig(output_name)
plt.close()
print(f"Результат сохранен: {output_name}, h_KS = {val_hks:.4f}")
if __name__ == "__main__":
files_to_process = ['1.xlsx', '2.xlsx', '3.xlsx']
process_files(files_to_process) 