短划线和极地线; RAM 使用量不断增加

问题描述 投票:0回答:1

我制作了一个本地仪表板应用程序,让学生能够有效地查找/研究他们的(测量)数据。为了进一步发展,我尝试从 pandas 和 duckdb 过渡到 Polars。经过几周的工作将其集成到这个广泛的应用程序中,我意识到我遇到了一个主要问题。

该应用程序以前很稳定,但现在有了 Polars,RAM 占用空间(pythonw.exe 进程的)随着每次连续的回调而膨胀。虽然应用程序启动时大约为 100 MB;每个回调都会增加大约 5MB 的大小。我似乎还没有稳定下来;已达到 1500 MB,并且仍在增长。

我有点卡住了,非常感谢一些如何解决这个问题的建议。

我做了一个最小示例来说明这个问题。如果我使用“polars_check=True”运行它,那么我从 98MB 开始,经过 100 次迭代后它变成了 261MB。如果我使用“polars_check”=False(即 pandas)来执行此操作,那么我以 98MB 开始和结束。

import pathlib, os, shutil
import polars as pl, pandas as pd, numpy as np, datetime as dt

from dash import Dash, dcc, html, Input, Output
import plotly.graph_objects as go


#Check-input
polars_check = True ### Whether the example returns with polars or with pandas.

if polars_check: #To accomdate the slower data retrieval with pandas.
    interval_time = 3E3
else:
    interval_time = 3E3

#Constants
folder = pathlib.Path(r'C:\PerovskiteCell example')

n_files = 100 #Number of files in folder
n_lines = 500000 #Number of total lines in folder
n_cols = 25


#Generating sample data in example folder (Only once).
if not folder.exists():

    size = int(n_lines / n_files)
    col = np.linspace(-1E3, 1E3, num=size)

    df = pl.DataFrame({f'col{n}': col for n in range(n_cols)})

    # Creating folder & files
    os.makedirs(folder)

    f_path0 = folder.joinpath('0.csv')
    df.write_csv(f_path0)

    for n in range(1, n_files):
        shutil.copy2(f_path0, folder.joinpath(f'{n}.csv'))


#Functions
def pl_data():
    """Retrieves data via the polars route"""
    
    lf = (pl.scan_csv(folder.joinpath(f'{n}.csv'),
                                schema={f'col{n}': pl.Float64 for n in range(n_cols)})
                            
                            .select(pl.all().get(n)) for n in range(n_files))
    
    lf = pl.concat(lf)
    lf = lf.select('col0', 'col1')

    return lf.collect()


def pd_data():
    """Retrieves data via the pandas route"""

    dfs = (pd.read_csv(folder.joinpath(f'{n}.csv'), usecols=['col0', 'col1']).iloc[n:n+1]
                                         for n in range(n_files))
    
    return pd.concat(dfs, ignore_index=True)



#App (initialization)
app = Dash()
app.layout = html.Div([dcc.Graph(id='graph'),
                        dcc.Interval(id = 'check', 
                                        interval = interval_time,
                                        max_intervals = 100)])


@app.callback(
    Output('graph', 'figure'),
    Input('check', 'n_intervals'))

def plot(_):

    #Data retrieval
    if polars_check:
        df = pl_data()
    else:
        df = pd_data()

    #Plotting
    fig = go.Figure()
    trace = go.Scattergl(x = list(df['col0']), y=list(df['col1']), mode='lines+markers')

    fig.add_trace(trace)
    fig.update_xaxes(title = str(dt.datetime.now()))

    return fig


if __name__ == '__main__':
    app.run(debug=False, port = 8050)
python flask plotly-dash python-polars
1个回答
0
投票

您可以尝试使用垃圾收集器的python包来清空未使用的内存。希望有帮助。

gc.enable()
gc.collect(generation=2)
© www.soinside.com 2019 - 2024. All rights reserved.