Update app.py
Browse files
app.py
CHANGED
|
@@ -1,98 +1,106 @@
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
def process_data():
|
| 7 |
try:
|
| 8 |
-
# Đọc file
|
| 9 |
-
thuoc_df
|
| 10 |
-
thuoc_plt
|
| 11 |
-
icd_plt
|
| 12 |
-
xetnghiem_df
|
| 13 |
|
| 14 |
# ==================== 1. LỌC PLT < 100 ====================
|
| 15 |
-
|
|
|
|
| 16 |
plt_df['Kết quả XN'] = pd.to_numeric(plt_df['Kết quả XN'], errors='coerce')
|
| 17 |
plt_low = plt_df[plt_df['Kết quả XN'] < 100].copy()
|
| 18 |
plt_low = plt_low[['Mã KCB', 'Tên XN', 'Kết quả XN', 'Ngày KQ']].rename(columns={'Mã KCB': 'makcb'})
|
| 19 |
|
| 20 |
if plt_low.empty:
|
| 21 |
-
return None, "Không
|
| 22 |
|
| 23 |
# ==================== 2. Chuẩn hóa mabhyt ====================
|
| 24 |
-
def
|
| 25 |
if pd.isna(x): return np.nan
|
| 26 |
return int(str(x).replace('.', ''))
|
| 27 |
|
| 28 |
-
thuoc_plt['mabhyt_norm'] = thuoc_plt['mabhyt'].apply(
|
| 29 |
-
thuoc_df['mabhyt_norm']
|
| 30 |
|
| 31 |
-
thuoc_full = thuoc_df.merge(thuoc_plt[['mabhyt_norm', 'hoatchat']],
|
|
|
|
| 32 |
|
| 33 |
# ==================== 3. Loại bệnh nhân có chẩn đoán trong ICD_PLT ====================
|
| 34 |
exclude_icds = set(icd_plt['maicd'].dropna().astype(str).str.strip())
|
| 35 |
|
| 36 |
-
def
|
| 37 |
if pd.isna(icd_str): return False
|
| 38 |
-
|
| 39 |
-
return any(code in exclude_icds for code in codes)
|
| 40 |
|
| 41 |
-
thuoc_full['exclude'] = thuoc_full['maicd'].apply(
|
| 42 |
thuoc_clean = thuoc_full[~thuoc_full['exclude']].copy()
|
| 43 |
|
| 44 |
# ==================== 4. Chỉ giữ bệnh nhân có PLT < 100 ====================
|
| 45 |
valid_patients = set(plt_low['makcb'])
|
| 46 |
-
thuoc_final = thuoc_clean[thuoc_clean['makcb'].isin(valid_patients)]
|
| 47 |
|
| 48 |
if thuoc_final.empty:
|
| 49 |
-
return None, "
|
| 50 |
|
| 51 |
-
|
| 52 |
-
thuoc_cols = ['makcb','hoten','ngaysinh','maicd','chandoan','ngaychidinh','maview',
|
| 53 |
'mabhyt','hoatchat','tenhh','dvt','hamluong','SL','cachdung','BS','duongdung','lieudung']
|
| 54 |
-
thuoc_final = thuoc_final[
|
| 55 |
|
| 56 |
-
# ==================== 5. Ghép cartesian
|
| 57 |
result = thuoc_final.merge(plt_low, on='makcb', how='inner')
|
|
|
|
| 58 |
|
| 59 |
-
# Sắp xếp đẹp
|
| 60 |
-
result = result.sort_values(['makcb', 'hoten', 'ngaychidinh', 'hoatchat', 'Ngày KQ'])
|
| 61 |
-
|
| 62 |
-
# Đúng thứ tự 20 cột như yêu cầu
|
| 63 |
final_cols = ['makcb','hoten','ngaysinh','maicd','chandoan','ngaychidinh','maview',
|
| 64 |
'mabhyt','hoatchat','tenhh','dvt','hamluong','SL','cachdung','BS','duongdung','lieudung',
|
| 65 |
'Tên XN','Kết quả XN','Ngày KQ']
|
| 66 |
result = result[final_cols]
|
| 67 |
|
| 68 |
-
# Lưu file
|
| 69 |
-
|
| 70 |
-
result.to_excel(
|
| 71 |
|
| 72 |
summary = f"""
|
| 73 |
HOÀN TẤT!
|
| 74 |
-
|
| 75 |
-
Sau khi loại chẩn đoán PLT:
|
| 76 |
-
Tổng
|
| 77 |
-
Đã lưu file: {output_file}
|
| 78 |
"""
|
| 79 |
-
return
|
| 80 |
|
| 81 |
except Exception as e:
|
| 82 |
return None, f"Lỗi: {str(e)}"
|
| 83 |
|
| 84 |
-
#
|
| 85 |
-
with gr.Blocks(title="Lọc
|
| 86 |
-
gr.Markdown("# Lọc bệnh nhân có PLT < 100 và loại chẩn đoán
|
| 87 |
-
gr.Markdown("Upload đủ 4 file: thuoc.xlsx, Thuoc_PLT.xlsx, ICD_PLT.xlsx, xetnghiem.xlsx")
|
| 88 |
|
| 89 |
with gr.Row():
|
| 90 |
-
|
| 91 |
-
|
| 92 |
with gr.Row():
|
| 93 |
-
|
| 94 |
-
|
|
|
|
|
|
|
| 95 |
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
demo.launch()
|
|
|
|
| 1 |
+
# app.py – ĐÃ SỬA HOÀN CHỈNH, CÓ Ô UPLOAD FILE
|
| 2 |
import gradio as gr
|
| 3 |
import pandas as pd
|
| 4 |
import numpy as np
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
def process(upload_thuoc, upload_thuoc_plt, upload_icd_plt, upload_xetnghiem):
|
| 8 |
+
if None in [upload_thuoc, upload_thuoc_plt, upload_icd_plt, upload_xetnghiem]:
|
| 9 |
+
return None, "Vui lòng upload đủ 4 file!"
|
| 10 |
|
|
|
|
| 11 |
try:
|
| 12 |
+
# Đọc file từ upload
|
| 13 |
+
thuoc_df = pd.read_excel(upload_thuoc)
|
| 14 |
+
thuoc_plt = pd.read_excel(upload_thuoc_plt)
|
| 15 |
+
icd_plt = pd.read_excel(upload_icd_plt)
|
| 16 |
+
xetnghiem_df = pd.read_excel(upload_xetnghiem)
|
| 17 |
|
| 18 |
# ==================== 1. LỌC PLT < 100 ====================
|
| 19 |
+
plt_mask = xetnghiem_df['Tên XN'].str.contains('PLT', case=False, na=False)
|
| 20 |
+
plt_df = xetnghiem_df[plt_mask].copy()
|
| 21 |
plt_df['Kết quả XN'] = pd.to_numeric(plt_df['Kết quả XN'], errors='coerce')
|
| 22 |
plt_low = plt_df[plt_df['Kết quả XN'] < 100].copy()
|
| 23 |
plt_low = plt_low[['Mã KCB', 'Tên XN', 'Kết quả XN', 'Ngày KQ']].rename(columns={'Mã KCB': 'makcb'})
|
| 24 |
|
| 25 |
if plt_low.empty:
|
| 26 |
+
return None, "Không có bệnh nhân nào PLT < 100"
|
| 27 |
|
| 28 |
# ==================== 2. Chuẩn hóa mabhyt ====================
|
| 29 |
+
def norm_mabhyt(x):
|
| 30 |
if pd.isna(x): return np.nan
|
| 31 |
return int(str(x).replace('.', ''))
|
| 32 |
|
| 33 |
+
thuoc_plt['mabhyt_norm'] = thuoc_plt['mabhyt'].apply(norm_mabhyt)
|
| 34 |
+
thuoc_df['mabhyt_norm'] = thuoc_df['mabhyt'].apply(norm_mabhyt)
|
| 35 |
|
| 36 |
+
thuoc_full = thuoc_df.merge(thuoc_plt[['mabhyt_norm', 'hoatchat']],
|
| 37 |
+
on='mabhyt_norm', how='left')
|
| 38 |
|
| 39 |
# ==================== 3. Loại bệnh nhân có chẩn đoán trong ICD_PLT ====================
|
| 40 |
exclude_icds = set(icd_plt['maicd'].dropna().astype(str).str.strip())
|
| 41 |
|
| 42 |
+
def has_excluded(icd_str):
|
| 43 |
if pd.isna(icd_str): return False
|
| 44 |
+
return any(c.strip() in exclude_icds for c in str(icd_str).split(';'))
|
|
|
|
| 45 |
|
| 46 |
+
thuoc_full['exclude'] = thuoc_full['maicd'].apply(has_excluded)
|
| 47 |
thuoc_clean = thuoc_full[~thuoc_full['exclude']].copy()
|
| 48 |
|
| 49 |
# ==================== 4. Chỉ giữ bệnh nhân có PLT < 100 ====================
|
| 50 |
valid_patients = set(plt_low['makcb'])
|
| 51 |
+
thuoc_final = thuoc_clean[thuoc_clean['makcb'].isin(valid_patients)]
|
| 52 |
|
| 53 |
if thuoc_final.empty:
|
| 54 |
+
return None, "Sau khi loại chẩn đoán PLT → không còn bệnh nhân nào"
|
| 55 |
|
| 56 |
+
cols_thuoc = ['makcb','hoten','ngaysinh','maicd','chandoan','ngaychidinh','maview',
|
|
|
|
| 57 |
'mabhyt','hoatchat','tenhh','dvt','hamluong','SL','cachdung','BS','duongdung','lieudung']
|
| 58 |
+
thuoc_final = thuoc_final[cols_thuoc]
|
| 59 |
|
| 60 |
+
# ==================== 5. Ghép cartesian ====================
|
| 61 |
result = thuoc_final.merge(plt_low, on='makcb', how='inner')
|
| 62 |
+
result = result.sort_values(['makcb', 'ngaychidinh', 'hoatchat', 'Ngày KQ'])
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
final_cols = ['makcb','hoten','ngaysinh','maicd','chandoan','ngaychidinh','maview',
|
| 65 |
'mabhyt','hoatchat','tenhh','dvt','hamluong','SL','cachdung','BS','duongdung','lieudung',
|
| 66 |
'Tên XN','Kết quả XN','Ngày KQ']
|
| 67 |
result = result[final_cols]
|
| 68 |
|
| 69 |
+
# Lưu file
|
| 70 |
+
output_path = "/tmp/KetQua_PLT_duoi_100_FULL.xlsx"
|
| 71 |
+
result.to_excel(output_path, index=False)
|
| 72 |
|
| 73 |
summary = f"""
|
| 74 |
HOÀN TẤT!
|
| 75 |
+
• Bệnh nhân có PLT < 100 : {plt_low['makcb'].nunique()}
|
| 76 |
+
• Sau khi loại chẩn đoán PLT : {result['makcb'].nunique()} bệnh nhân
|
| 77 |
+
• Tổng dòng kết quả (thuốc × PLT) : {len(result):,} dòng
|
|
|
|
| 78 |
"""
|
| 79 |
+
return output_path, summary
|
| 80 |
|
| 81 |
except Exception as e:
|
| 82 |
return None, f"Lỗi: {str(e)}"
|
| 83 |
|
| 84 |
+
# ==================== GIAO DIỆN GRADIO ====================
|
| 85 |
+
with gr.Blocks(title="Lọc PLT < 100 + Loại chẩn đoán PLT") as demo:
|
| 86 |
+
gr.Markdown("# Lọc bệnh nhân có PLT < 100 và loại bỏ chẩn đoán liên quan tiểu cầu")
|
|
|
|
| 87 |
|
| 88 |
with gr.Row():
|
| 89 |
+
thuoc = gr.File(label="1. thuoc.xlsx", file_types=[".xlsx"])
|
| 90 |
+
thuoc_plt = gr.File(label="2. Thuoc_PLT.xlsx", file_types=[".xlsx"])
|
| 91 |
with gr.Row():
|
| 92 |
+
icd_plt = gr.File(label="3. ICD_PLT.xlsx", file_types=[".xlsx"])
|
| 93 |
+
xetnghiem = gr.File(label="4. xetnghiem.xlsx", file_types=[".xlsx"])
|
| 94 |
+
|
| 95 |
+
btn = gr.Button("CHẠY XỬ LÝ", variant="primary", size="lg")
|
| 96 |
|
| 97 |
+
output_file = gr.File(label="TẢI KẾT QUẢ EXCEL")
|
| 98 |
+
output_text = gr.Textbox(label="Thông báo chi tiết", lines=8)
|
| 99 |
+
|
| 100 |
+
btn.click(
|
| 101 |
+
fn=process,
|
| 102 |
+
inputs=[thuoc, thuoc_plt, icd_plt, xetnghiem],
|
| 103 |
+
outputs=[output_file, output_text]
|
| 104 |
+
)
|
| 105 |
|
| 106 |
demo.launch()
|