123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- from flask import Flask, jsonify, request
- import requests
- from io import StringIO
- import pandas as pd
- import numpy as np
- from sklearn.linear_model import LinearRegression
- from sklearn.metrics import mean_squared_error
- from sklearn.model_selection import train_test_split
- import json
- app = Flask(__name__)
- def detect_outlier(data):
- # 计算平均值和标准差
- mean = np.mean(data)
- std = np.std(data)
- # 设定上下界
- lower = mean - 1 * std
- upper = mean + 1 * std
- # 创建一个空列表,用于存储新列的数据
- result = []
- # 遍历原列的数据,判断是否为异常值
- for x in data:
- # 如果小于下界或大于上界,认为是异常值,标记为1
- if x < lower or x > upper:
- result.append(1)
- # 否则认为是正常值,标记为0
- else:
- result.append(0)
- # 返回新列的数据
- return result
- # 异常值剔除
- @app.route('/abnormal', methods=['POST'])
- def process_data():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 200, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- # 对每一列的数据调用函数,生成新列
- for col in dataframe.columns:
- if col != '时间': # 跳过 时间列
- dataframe[col + '_是否异常'] = detect_outlier(dataframe[col]) # 新列的名字为原列名加_是否异常
- # 返回处理后的数据
- result = {'status': 200, 'data': dataframe.to_dict(orient='records'), 'msg': 'Successfully'}
- print(jsonify(result))
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- # 缺失值补全
- @app.route('/completion', methods=['POST'])
- def process_data1():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 500, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- # 用数值型列的平均值插补缺失值
- dataframe.fillna(dataframe.select_dtypes(include=np.number).mean().round(3), inplace=True)
- # 返回处理后的数据
- result = {'status': 200, 'data': dataframe.to_dict(orient='records')}
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- def alarm_suppression(alarms, threshold=0.6):
- """
- 输入:
- alarms: 报警序列,由 0 和 1 组成
- 输出:
- is_true_alarms: 是否是真的报警序列,由 True 和 False 组成
- """
- # 定义虚警门限
- # threshold = 0.6
- # 遍历报警序列,如果报警值超过门限,则认为是真的报警
- alarms = alarms.apply(pd.to_numeric, errors='coerce')
- # 遍历报警序列的每一列,如果列中的值超过门限,则认为是真的报警
- # is_true_alarms = alarms.apply(lambda col: col > threshold, axis=0)
- # 遍历每一列,创建新的列以标记是否是真实的报警
- for column_name in alarms:
- new_column_name = f"{column_name}_是否虚警"
- alarms[new_column_name] = alarms[column_name] > threshold
- return alarms
- def list_tran_json(list):
- str_json = json.dumps(list, ensure_ascii=False, indent=2)
- return str_json
- # 虚警抑制
- @app.route('/false_alarm', methods=['POST'])
- def process_data2():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- # 虚警门限
- threshold = data.get('threshold')
- faultCode = data.get('faultCode')
- threshold = 0.3
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 500, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- columns_to_remove = ['时间', '故障名称']
- excluded_columns = [col for col in columns_to_remove if col in dataframe.columns]
- excluded_columns_data = dataframe[excluded_columns]
- dataframe = dataframe.drop(columns=excluded_columns, errors='ignore')
- # 用数值型列的平均值插补缺失值
- is_true_alarms = alarm_suppression(dataframe, float(threshold))
- # 返回处理后的数据
- # result_df = pd.DataFrame(is_true_alarms, columns=dataframe.columns)
- result_df = pd.concat([is_true_alarms, excluded_columns_data], axis=1)
- # 返回处理后的数据
- # result = {'status': 200, 'data': result_df.to_dict(orient='records')}
- data_json = [{'故障编码': faultCode, '是否虚警': '是'}]
- result = {'status': 200, 'data': data_json}
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- # 故障诊断
- @app.route('/fault_diagnosis', methods=['POST'])
- def process_data3():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 500, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- # 计算均值
- xm = np.mean(dataframe.iloc[:, 1])
- xstd = np.std(dataframe.iloc[:, 1]) # 标准差
- kur = ((sum((dataframe.iloc[:, 1] - xm) ** 4)) / len(dataframe.iloc[:, 1])) / (xstd ** 4) # 峭度
- # 结果图片上传
- # // 文件上传 http://localhost:9090/als/resource/oss/upload
- # 文件上传API ,返回结果 {
- # "code": 200,
- # "msg": "操作成功",
- # "data": {
- # "ossId": "236309167646711808"
- # }
- # }
- # python 调用 API 得到ossId 返回
- data1 = {"result" : "字符串结果", "ossId": 236309167646711808}
- result = {'status': 200, 'data': data1}
- # 最终返回结果
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- # 深度隔离
- @app.route('/fault_isolation', methods=['POST'])
- def process_data4():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 500, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- # 计算均值
- xm = np.mean(dataframe.iloc[:, 1])
- # 判断输出是否故障
- if xm > 0.1:
- result = {'status': 200, 'data': '发动机振动故障'}
- else:
- result = {'status': 200, 'data': '发动机振动正常'}
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- # 故障预测
- @app.route('/fault_prediction', methods=['POST'])
- def process_data5():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 500, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- X_train, X_test, y_train, y_test = train_test_split(dataframe.iloc[:, :-1], dataframe.iloc[:, -1],
- test_size=0.05, random_state=42)
- # 训练线性回归模型
- model = LinearRegression()
- model.fit(X_train, y_train)
- # 对测试集进行预测
- y_pred = model.predict(X_test)
- # 计算均方误差
- mse = mean_squared_error(y_test, y_pred)
- # 判断输出是否故障
- if np.mean(y_pred) > 2:
- result = {'status': 200, 'data': '发动机寿命后期'}
- else:
- result = {'status': 200, 'data': '发动机寿命前期'}
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- # 定义合理参数范围的字典,实际应用中需依据具体飞机型号及飞行手册设定
- PARAMETER_RANGES = {
- "发动机排气温度": (500, 1200), # 示例范围,单位:摄氏度
- "喘振值": (0.8, 1.2), # 示例范围,具体范围需根据实际情况设定
- "时间": None, # 时间一般不设定范围,但确保数据连续性
- "机匣加速": (-200, 200), # 示例范围,单位:m/s^2
- "机匣振幅": (0, 0.1), # 示例范围,单位:毫米
- "机匣频率": (50, 500), # 示例范围,单位:Hz
- "燃油流量": (0, 10), # 示例范围,单位:kg/s,具体根据发动机规格
- "风扇转子转速": (5000, 12000), # 示例范围,单位:RPM
- "高压压气机转子转数": (8000, 15000), # 示例范围,单位:RPM
- }
- def check_parameter_validity(value, range_info):
- """检查单个参数值是否在合理范围内"""
- if range_info is None or (value >= range_info[0] and value <= range_info[1]):
- return True
- return False
- def calculate_testability(df_flight_params: pd.DataFrame) -> float:
- """
- 根据飞参数据评估可测试性得分。
- 参数:
- df_flight_params (pd.DataFrame): 包含飞参数据的DataFrame。
- 返回:
- float: 可测试性得分,范围0-1,值越接近1表示数据越符合预期,可测试性越高。
- """
- total_rows = len(df_flight_params)
- valid_count = 0
- for param in PARAMETER_RANGES.keys():
- if param in df_flight_params.columns:
- # 检查该参数的每个值是否都在合理范围内
- valid_for_param = df_flight_params[param].apply(check_parameter_validity, args=(PARAMETER_RANGES[param],))
- valid_count += valid_for_param.sum()
- # 计算整体有效性百分比作为可测试性得分
- testability_score = valid_count / (total_rows * len(PARAMETER_RANGES)) if total_rows > 0 else 0
- return testability_score
- # 测试性
- @app.route('/testability', methods=['POST'])
- def process_data6():
- try:
- # 从请求中获取数据
- data = request.get_json()
- # 从在线数据链接下载 CSV 数据
- data_url = data.get('url')
- response = requests.get(data_url)
- # 检查下载是否成功
- if response.status_code != 200:
- error_message = {'status': 200, 'message': 'Failed to download CSV data'}
- return jsonify(error_message)
- # 将 CSV 数据转换为 Pandas DataFrame
- response.encoding = 'UTF-8'
- csv_data = StringIO(response.text)
- dataframe = pd.read_csv(csv_data, index_col=False, encoding='UTF-8')
- df_flight_params = pd.DataFrame(dataframe)
- # 计算可测试性得分
- testability = calculate_testability(df_flight_params)
- res = f"根据飞参数据评估,可测试性得分为: {testability:.2f}"
- result = {'status': 200, 'data': res}
- return jsonify(result)
- except Exception as e:
- error_message = {'status': 500, 'message': str(e)}
- return jsonify(error_message)
- app.debug = True
- if __name__ == '__main__':
- # 启动 Flask 应用
- app.run(debug=True, port=8888, host='0.0.0.0')
|