[py]可迭代对象-求最值

for .. in ..方式遍历可迭代对象

而非下标


## 判断是否可迭代
from collections import Iterable
print(isinstance(123,Iterable))
print(isinstance('abc',Iterable))
print(isinstance([],Iterable))
print(isinstance({},Iterable))


## 打印str下标和值
for k,v in enumerate('abc'):
    print(k,v)
print('------------')
for k,v in enumerate({'a':1,'b':2}):
    print(k,v)
  • 求arr的最大值
  • 求arr的最大的2个值
  • 求arr的max和min
# 求arr的最大值

arr = [11,2,3]
max_num = 0
for i in arr:
    if i > max_num:
        max_num = i
print(max_num)


# 找出arr最大的两个值
## 思路,找2个游标,看i落在哪里了.

max_num = 0
sec_num = 0
arr = [1, 2, 2, 3]

for i in arr:
    if i < sec_num:
        sec_num = i
    elif i > sec_num and i < max_num:
        sec_num = i
    elif i > max_num:
        sec_num = max_num
        max_num = i

print(sec_num, max_num)


# 找出最大最小值
# 迭代查找一个list中最小和最大值,并返回一个tuple
arr = [1, 2, 1, 3, 4, 5]


def get_min_max(arr):
    max_num = arr[0]
    min_num = arr[0]
    if len(arr) == 0:
        return ""
    for i in arr:
        if i < min_num:
            min_num = i
        if i > max_num:
            max_num = i
    print(min_num, max_num)
    return (min_num, max_num)


get_min_max(arr)

转载于:https://www.cnblogs.com/iiiiiher/p/8328998.html

import os import random import subprocess import serial import time from scipy.signal import peak_widths, find_peaks from instruments import optical_spectrum_analyzer import pandas as pd import numpy as np from instruments import oscilloscope # 配置串口参数 port = 'COM3' baudrate = 115200 # 初始化串口对象 try: ser = serial.Serial(port, baudrate, timeout=1) print("成功打开串口") except serial.SerialException as e: print(f"打开串口失败: {e}") exit(1) # 初始化光谱分析仪 osa = optical_spectrum_analyzer.Yokogawa_AQ6375B() # 读取目标强度数据 target_spec_df = pd.read_csv('Target.csv') target_spec_intensity = np.array(target_spec_df["Intensity"]) target_spec_intensity[target_spec_intensity < -60] = -60 # 初始化光谱分析仪 osc = oscilloscope.MSO_X_3102A() # 读取目标强度数据 target_auto_df = pd.read_csv('t-Target.csv') target_auto_intensity = np.array(target_auto_df["Intensity"]) # target_auto_intensity[target_auto_intensity < 0.05] = 0.05 # 初始化误差跟踪变量 min_error = float('inf') min_error_value = None prev_error = float('inf') prev_instruction = None error_records = [] # 用于结果文件命名的计数器 file_counter = 88 # 全局参数配置 PLOT_FONT = {'fontsize': 30, 'fontweight': 'bold', 'family': 'Times New Roman'} GAUSSIAN_SIGMA = 5 # 高斯滤波参数 WEIGHTS = {'spectrum': 0.8, 'autocorr': 0.5} # 误差权重 # 增强型误差计算函数 def autocorr_error(y_true, y_pred, x_values): """自相关曲线综合误差计算""" metrics = {} try: # 峰位置误差 peak_true = x_values[np.argmax(y_true)] peak_pred = x_values[np.argmax(y_pred)] metrics['position'] = np.abs(peak_true - peak_pred) # 脉冲宽度误差 (FWHM) _, _, width_true, _ = peak_widths(y_true, [np.argmax(y_true)], rel_height=0.5) _, _, width_pred, _ = peak_widths(y_pred, [np.argmax(y_pred)], rel_height=0.5) metrics['width'] = np.abs(width_true[0] - width_pred[0]) * (x_values[1] - x_values[0]) # 波形相似性 metrics['correlation'] = np.corrcoef(y_true, y_pred)[0, 1] # 综合误差计算(可调整权重) metrics['total'] = (0 * metrics['position'] + 0.5 * metrics['width'] + 0.05 * (1 - metrics['correlation'])) except: metrics['total'] = float('inf') return metrics def mse_valid(y_true, y_pred, invalid_val=-65): """有效数据均方误差(双条件过滤)""" mask = (y_true > invalid_val) & (y_pred > -65) # 新增y_pred强度过滤 if np.sum(mask) < 1: # 处理无有效数据情况 return float('inf') return np.mean((y_true[mask] - y_pred[mask]) ** 2) def center_wavelength_error(y_true, y_pred, x_values): """中心波长误差计算(质心法)""" try: # 有效数据过滤 valid_mask = (y_pred > -65) & (y_true > -65) if np.sum(valid_mask) < 3: return 1000 # 数据不足时返回大误差 # 计算质心 centroid_true = np.sum(x_values[valid_mask] * y_true[valid_mask]) / np.sum(y_true[valid_mask]) centroid_pred = np.sum(x_values[valid_mask] * y_pred[valid_mask]) / np.sum(y_pred[valid_mask]) return np.abs(centroid_true - centroid_pred) except: return 1000 # 异常处理 # def peak_alignment_error(y_true, y_pred, x_values): # """带强度限制的峰对齐误差""" # # 应用强度过滤 # valid_mask = y_pred > -60 # y_pred_filtered = y_pred[valid_mask] # x_filtered = x_values[valid_mask] # # # 目标峰检测 # try: # peaks_true, _ = find_peaks(y_true, height=-80, distance=10) # peak_true_pos = x_values[peaks_true[0]] # except IndexError: # return 1000 # 目标无峰惩罚 # # # 预测峰检测 # if len(y_pred_filtered) == 0: # return 1000 # try: # peaks_pred, _ = find_peaks(y_pred_filtered, height=-80, distance=10) # peak_pred_pos = x_filtered[peaks_pred[0]] # except IndexError: # return 1000 # # return 0.7 * np.abs(peak_true_pos - peak_pred_pos) + 0.3 * np.abs( # y_true[peaks_true[0]] - y_pred_filtered[peaks_pred[0]]) def spectral_correlation(y_true, y_pred): """带强度限制的光谱相关性""" mask = y_pred > -65 # 仅考虑预测>-65的区域 if np.sum(mask) < 2: # 至少需要2个点计算相关系数 return 0.0 return np.corrcoef(y_true[mask], y_pred[mask])[0, 1] while True: try: # 生成控制指令 if prev_instruction: try: prev_values = prev_instruction.strip().split(',') if len(prev_values) == 3 and all(v.strip() for v in prev_values): base_values = list(map(int, prev_values)) # 生成在基附近波动的参数 value1 = max(40, min(65, random.randint(base_values[0]-2, base_values[0]+2))) value2 = max(15, min(35, random.randint(base_values[1]-2, base_values[1]+2))) value3 = max(0, min(25, random.randint(base_values[2]-2, base_values[2]+2))) else: raise ValueError("Invalid instruction format") except (ValueError, IndexError) as e: print(f"指令解析失败: {e}") value1 = random.randint(40, 65) value2 = random.randint(15, 35) value3 = random.randint(0, 20) else: value1 = random.randint(40, 65) value2 = random.randint(15, 35) value3 = random.randint(0, 20) # 发送指令到Arduino instruction = f"{value1},{value2},{value3}\n" ser.write(instruction.encode('utf-8')) print(f"发送指令: {instruction.strip()}") # 等待设备响应 time.sleep(2) try: reply = ser.readline().decode('utf-8').strip() if reply: print(f"收到回复: {reply}") except serial.SerialException as e: print(f"读取回复失败: {e}") # 获取并处理光谱数据 Wavelength, Intensity = osa.measure(1) Intensity[Intensity < -65] = -65 spec_metrics = { 'mse': mse_valid(target_spec_intensity, Intensity), # 'peak': peak_alignment_error(target_spec_intensity, Intensity, Wavelength), 'centroid': center_wavelength_error(target_spec_intensity, Intensity, Wavelength), 'corr': spectral_correlation(target_spec_intensity, Intensity) } spec_error = (0.6 * spec_metrics['mse'] + 0 * spec_metrics['peak'] + 0.3 * spec_metrics['centroid'] + 0.8 * (1-spec_metrics['corr'])) # 获取示波器数据 measurement = osc.measure(1) if measurement is not None: Time, Intensity = measurement # Intensity[Intensity < 0.05] = 0.05 # 计算误差 auto_metrics = autocorr_error(target_auto_intensity, Intensity, Time) auto_error = auto_metrics['total'] # 计算总误差 total_error = WEIGHTS['spectrum'] * spec_error + WEIGHTS['autocorr'] * auto_error print(f"当前误差: {total_error:.2f}") # 更新小误差和小误差角度 if total_error < min_error: min_error = total_error min_error_value = instruction print(f"发现更优解: {min_error_value.strip()} 误差: {min_error:.2f}") # 记录误差数据 error_records.append({'指令': instruction.strip(), '误差': total_error}) pd.DataFrame(error_records).to_csv('all_errors1.csv', index=False) # 运行 optical_spectrum_analyzer.py 文件 try: subprocess.run(['python', 'optical_spectrum_analyzer.py']) if os.path.exists('result.csv'): os.rename('result.csv', f'gp{file_counter}.csv') except Exception as e: print(f"运行 optical_spectrum_analyzer.py 失败: {e}") # 运行 oscilloscope.py 文件 try: subprocess.run(['python', 'oscilloscope.py']) if os.path.exists('result.csv'): os.rename('result.csv', f'zxg{file_counter}.csv') except Exception as e: print(f"运行 oscilloscope.py 失败: {e}") # 运行停止鼠标控制保存.py 文件 try: subprocess.run(['python', '鼠标控制保存.py']) print(f"运行 鼠标控制保存") except Exception as e: print(f"运行 鼠标控制保存.py 失败: {e}") file_counter += 1 # 停止 1 秒 time.sleep(1) # 判断收敛条件 if total_error < 5: print(f"达到目标精度! 终指令: {min_error_value.strip()}") ser.write(min_error_value.encode('utf-8')) break # 更新搜索策略 if total_error < 20 and abs(prev_error - total_error) > 3: prev_error = total_error prev_instruction = instruction else: prev_instruction = None except Exception as e: print(f"运行异常: {e}") prev_instruction = None # 出现异常时重置搜索基准 ser.close()说明该算法具体的细节,如何避免不收敛及局域问题,涉及具体数学细节
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值