Anonymous
Nuitka и PyQt6 указывают импорт для уменьшения размера exe (в настоящее время ~ 1 ГБ)
Сообщение
Anonymous » 22 дек 2025, 22:25
Я работаю над проектом по разработке простого приложения на основе сценария Python для анализа данных, использующего PyQt6 для форматирования приложения и использующего Nuitka для создания exe-файла. (Да, я пробовал использовать PyInstaller. Антивирус моей компании продолжает блокировать его.)
Приложение извлекает данные из CSV-файла с помощью Pandas, преобразует данные с помощью SciPy, а затем отображает данные с помощью MatPlotLib.
Я пытаюсь уменьшить размер exe-файла, чтобы его можно было легко использовать в моей лаборатории. Есть какие-нибудь предложения о том, как уменьшить импорт и уменьшить размер exe-файла? Ниже я приведу несколько выдержек:
Код: Выделить всё
from sys import argv, exit
from PyQt6.QtWidgets import QApplication
from gui_app import PyQtApp
if __name__== "__main__":
app = QApplication(argv)
main_app_instance = PyQtApp()
main_app_instance.show()
try:
exit(app.exec())
except SystemExit:
print('Closing Window...')
Код: Выделить всё
import sys
from os import path, getcwd
from pandas import DataFrame, read_csv
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QFileDialog, QTableView, QTextEdit, QGroupBox
)
from PyQt6.QtGui import QIcon, QPixmap
from data_model import PandasModel
from data_analyzer import analyze_cof_data
from graph_widget import MplGraphWidget
def resource_path(relative_path):
if hasattr(sys, "-MEIPASS"):
return path.join(sys.MEIPASS, relative_path)
return path.join(path.abspath("./images/"), relative_path)
class PyQtApp(QWidget):
# Defines main window
def __init__(self):
super().__init__()
# Creates dataframe
self.df = None
# Window title
self.title = 'RCP Analysis'
# Window dimensions
self.left = 0
self.top = 0
self.width = 600
self.height = 900
# Sets up main window
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
# Displays widgets in init_ui
self.init_ui()
# Connects to file browser and searches for CSV files
def getFileName(self):
file_filter = 'Data File (*.csv)'
filePath, _ = QFileDialog.getOpenFileName(
parent=self,
caption='Select a data file',
directory=getcwd(),
filter=file_filter
)
if filePath:
self.dataSourceField.setText(filePath)
# Loads data from CSV into dataframe
def retrieveDataset(self):
# Defines path to source file
self.urlSource = self.dataSourceField.text()
if not self.urlSource or not path.exists(self.urlSource):
self.statusLabel.setText("Invalid filepath provided or file does not exist.")
return
try:
# Reads data from CSV
self.df = read_csv(
self.urlSource,
header=6,
usecols=[0,1],
names=["Time", "CoF"]
)
# Writes data into dataframe table
if isinstance(self.df, DataFrame):
self.df = self.df.dropna()
self.model = PandasModel(self.df)
self.table.setModel(self.model)
self.statusLabel.setText(f"Successfully loaded {len(self.df)} rows.")
self.table.horizontalHeader().setStretchLastSection(True)
else:
self.statusLabel.setText(f"Error: Loaded object is not a DataFrame (Type: {type(self.df)})")
except Exception as e:
self.statusLabel.setText(f"Erro loading file: {e}")
print(f"Error details: {e}")
# Begins data analysis
def launchAnalysis(self):
# Ensures data exists
if self.df is not None and isinstance(self.df, DataFrame) and not self.df.empty:
self.statusLabel.setText("Starting data analysis...")
self.results_text.clear()
try:
# Runs analysis
results = analyze_cof_data(self.df)
# Writes results in results text box
for line in results['summary']:
self.results_text.append(line)
# Graphs data in widget
self.graph_widget.plot_data(self.df["Time"], self.df["CoF"], "Raw CoF Data Plot")
# Success statement
self.statusLabel.setText("Analysis complete.")
print(f"Analyze complete. CoF: {results['avg_CoF']: .4f}, STDEV: {results['stdev_np']: .4f}")
# Error statement
except Exception as e:
self.statusLabel.setText(f"Error during analysis: {e}")
print(f"Error during analysis details: {e}")
# Failure statement
else:
self.statusLabel.setText("Cannot analyze: No data loaded.")
print("No data to analyze")
# Sets up user interface
def init_ui(self):
# Icon
icon = resource_path("QH_icon.ico")
self.setWindowIcon(QIcon(icon))
# Logo
logo = resource_path("QH_logo.png")
pixmap = QPixmap(logo)
logo_label = QLabel()
logo_label.setPixmap(pixmap)
self.layout.addWidget(logo_label)
# Defines UI layout
sourceLayout = QHBoxLayout()
self.layout.addLayout(sourceLayout)
# File browser widget
label = QLabel('&Data Source:')
self.dataSourceField = QLineEdit()
label.setBuddy(self.dataSourceField)
# Action buttons
buttonBrowse = QPushButton('&Browse', clicked=self.getFileName)
buttonRetrieve = QPushButton('&Get Data', clicked=self.retrieveDataset)
buttonLaunch = QPushButton('&Analyze', clicked=self.launchAnalysis)
# Organizes layout
sourceLayout.addWidget(label)
sourceLayout.addWidget(self.dataSourceField)
sourceLayout.addWidget(buttonBrowse)
sourceLayout.addWidget(buttonRetrieve)
# Table widget and "Analyze" button
self.table = QTableView()
self.layout.addWidget(self.table, 1)
self.layout.addWidget(buttonLaunch)
# Graph widget
self.graph_widget = MplGraphWidget(self)
self.layout.addWidget(self.graph_widget, 2)
# Group box to print results
results_group = QGroupBox("Analysis Results")
results_layout = QVBoxLayout()
self.results_text = QTextEdit()
self.results_text.setReadOnly(True)
results_layout.addWidget(self.results_text)
results_group.setLayout(results_layout)
self.layout.addWidget(results_group)
# Status bar for messages and errors
self.statusLabel = QLabel()
self.statusLabel.setText('Ready.')
self.layout.addWidget(self.statusLabel)
Код: Выделить всё
from numpy import mean, std
from pandas import DataFrame
from scipy.stats import zscore
from scipy.signal import detrend
def analyze_cof_data(df: DataFrame):
"""
Performs detrending, outlier filtering, and calculates mean/stdev for CoF data.
Returns a dictionary of results and stats summary strings.
"""
STDEV_THRESHOLD = 1
time_values = df["Time"].to_numpy()
signal_data = df["CoF"].to_numpy()
detrended_signal = detrend(signal_data, type='linear')
abs_signal = abs(detrended_signal)
z_score = abs(zscore(abs_signal))
is_inlier = z_score < STDEV_THRESHOLD
points_kept = len(abs_signal[is_inlier])
avg_CoF = mean(abs_signal)
stdev_np = std(abs_signal, ddof=1)
results_summary = [
f"Original number of points: {len(signal_data)}",
f"Points kept after detrending and {STDEV_THRESHOLD} Standard Deviation filter: {points_kept}",
f"The average CoF is: {avg_CoF: .4f}",
f"The Standard Deviation is: {stdev_np: .4f}"
]
return {
'abs_signal': abs_signal,
'avg_CoF': avg_CoF,
'stdev_np': stdev_np,
'summary': results_summary
}
Заранее благодарим за любые советы!
Подробнее здесь:
https://stackoverflow.com/questions/798 ... rently-1gb
1766431506
Anonymous
Я работаю над проектом по разработке простого приложения на основе сценария Python для анализа данных, использующего PyQt6 для форматирования приложения и использующего Nuitka для создания exe-файла. (Да, я пробовал использовать PyInstaller. Антивирус моей компании продолжает блокировать его.) Приложение извлекает данные из CSV-файла с помощью Pandas, преобразует данные с помощью SciPy, а затем отображает данные с помощью MatPlotLib. Я пытаюсь уменьшить размер exe-файла, чтобы его можно было легко использовать в моей лаборатории. Есть какие-нибудь предложения о том, как уменьшить импорт и уменьшить размер exe-файла? Ниже я приведу несколько выдержек: [code]from sys import argv, exit from PyQt6.QtWidgets import QApplication from gui_app import PyQtApp if __name__== "__main__": app = QApplication(argv) main_app_instance = PyQtApp() main_app_instance.show() try: exit(app.exec()) except SystemExit: print('Closing Window...') [/code] [code]import sys from os import path, getcwd from pandas import DataFrame, read_csv from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QTableView, QTextEdit, QGroupBox ) from PyQt6.QtGui import QIcon, QPixmap from data_model import PandasModel from data_analyzer import analyze_cof_data from graph_widget import MplGraphWidget def resource_path(relative_path): if hasattr(sys, "-MEIPASS"): return path.join(sys.MEIPASS, relative_path) return path.join(path.abspath("./images/"), relative_path) class PyQtApp(QWidget): # Defines main window def __init__(self): super().__init__() # Creates dataframe self.df = None # Window title self.title = 'RCP Analysis' # Window dimensions self.left = 0 self.top = 0 self.width = 600 self.height = 900 # Sets up main window self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.layout = QVBoxLayout() self.setLayout(self.layout) # Displays widgets in init_ui self.init_ui() # Connects to file browser and searches for CSV files def getFileName(self): file_filter = 'Data File (*.csv)' filePath, _ = QFileDialog.getOpenFileName( parent=self, caption='Select a data file', directory=getcwd(), filter=file_filter ) if filePath: self.dataSourceField.setText(filePath) # Loads data from CSV into dataframe def retrieveDataset(self): # Defines path to source file self.urlSource = self.dataSourceField.text() if not self.urlSource or not path.exists(self.urlSource): self.statusLabel.setText("Invalid filepath provided or file does not exist.") return try: # Reads data from CSV self.df = read_csv( self.urlSource, header=6, usecols=[0,1], names=["Time", "CoF"] ) # Writes data into dataframe table if isinstance(self.df, DataFrame): self.df = self.df.dropna() self.model = PandasModel(self.df) self.table.setModel(self.model) self.statusLabel.setText(f"Successfully loaded {len(self.df)} rows.") self.table.horizontalHeader().setStretchLastSection(True) else: self.statusLabel.setText(f"Error: Loaded object is not a DataFrame (Type: {type(self.df)})") except Exception as e: self.statusLabel.setText(f"Erro loading file: {e}") print(f"Error details: {e}") # Begins data analysis def launchAnalysis(self): # Ensures data exists if self.df is not None and isinstance(self.df, DataFrame) and not self.df.empty: self.statusLabel.setText("Starting data analysis...") self.results_text.clear() try: # Runs analysis results = analyze_cof_data(self.df) # Writes results in results text box for line in results['summary']: self.results_text.append(line) # Graphs data in widget self.graph_widget.plot_data(self.df["Time"], self.df["CoF"], "Raw CoF Data Plot") # Success statement self.statusLabel.setText("Analysis complete.") print(f"Analyze complete. CoF: {results['avg_CoF']: .4f}, STDEV: {results['stdev_np']: .4f}") # Error statement except Exception as e: self.statusLabel.setText(f"Error during analysis: {e}") print(f"Error during analysis details: {e}") # Failure statement else: self.statusLabel.setText("Cannot analyze: No data loaded.") print("No data to analyze") # Sets up user interface def init_ui(self): # Icon icon = resource_path("QH_icon.ico") self.setWindowIcon(QIcon(icon)) # Logo logo = resource_path("QH_logo.png") pixmap = QPixmap(logo) logo_label = QLabel() logo_label.setPixmap(pixmap) self.layout.addWidget(logo_label) # Defines UI layout sourceLayout = QHBoxLayout() self.layout.addLayout(sourceLayout) # File browser widget label = QLabel('&Data Source:') self.dataSourceField = QLineEdit() label.setBuddy(self.dataSourceField) # Action buttons buttonBrowse = QPushButton('&Browse', clicked=self.getFileName) buttonRetrieve = QPushButton('&Get Data', clicked=self.retrieveDataset) buttonLaunch = QPushButton('&Analyze', clicked=self.launchAnalysis) # Organizes layout sourceLayout.addWidget(label) sourceLayout.addWidget(self.dataSourceField) sourceLayout.addWidget(buttonBrowse) sourceLayout.addWidget(buttonRetrieve) # Table widget and "Analyze" button self.table = QTableView() self.layout.addWidget(self.table, 1) self.layout.addWidget(buttonLaunch) # Graph widget self.graph_widget = MplGraphWidget(self) self.layout.addWidget(self.graph_widget, 2) # Group box to print results results_group = QGroupBox("Analysis Results") results_layout = QVBoxLayout() self.results_text = QTextEdit() self.results_text.setReadOnly(True) results_layout.addWidget(self.results_text) results_group.setLayout(results_layout) self.layout.addWidget(results_group) # Status bar for messages and errors self.statusLabel = QLabel() self.statusLabel.setText('Ready.') self.layout.addWidget(self.statusLabel) [/code] [code]from numpy import mean, std from pandas import DataFrame from scipy.stats import zscore from scipy.signal import detrend def analyze_cof_data(df: DataFrame): """ Performs detrending, outlier filtering, and calculates mean/stdev for CoF data. Returns a dictionary of results and stats summary strings. """ STDEV_THRESHOLD = 1 time_values = df["Time"].to_numpy() signal_data = df["CoF"].to_numpy() detrended_signal = detrend(signal_data, type='linear') abs_signal = abs(detrended_signal) z_score = abs(zscore(abs_signal)) is_inlier = z_score < STDEV_THRESHOLD points_kept = len(abs_signal[is_inlier]) avg_CoF = mean(abs_signal) stdev_np = std(abs_signal, ddof=1) results_summary = [ f"Original number of points: {len(signal_data)}", f"Points kept after detrending and {STDEV_THRESHOLD} Standard Deviation filter: {points_kept}", f"The average CoF is: {avg_CoF: .4f}", f"The Standard Deviation is: {stdev_np: .4f}" ] return { 'abs_signal': abs_signal, 'avg_CoF': avg_CoF, 'stdev_np': stdev_np, 'summary': results_summary } [/code] Заранее благодарим за любые советы! Подробнее здесь: [url]https://stackoverflow.com/questions/79852974/nuitka-pyqt6-specifying-imports-to-reducing-exe-size-currently-1gb[/url]