Упрощенная загрузка данных столбца занимает слишком много времени - PullRequest
0 голосов
/ 29 января 2020

Я использую простой фрагмент кода в streamlit, который показывает фрейм данных, состоящий из Excel, который у меня есть. проблема заключается в том, что загрузка данных внутри столбца фильтра в области потока будет занимать слишком много времени. в этой области фильтра я выполняю поиск по названию материала, но для загрузки и отображения мне данных, которые я собираюсь выбрать, требуется даже 30 секунд. Как ее решить и как можно быстрее выбрать данные?

Код:

import streamlit as st
import pandas as pd

@st.cache
def load_data(nrows):
    df=pd.read_excel('materials.xlsx',nrows=nrows)
    return df

df=load_data(100000)

species = st.multiselect('SELECT THE MATERIAL', df['Name'])
new_df = df[(df['Name'].isin(species))]
st.write(new_df)

the excel file which has 20,000 rows by the way

и показать, как слишком медленно выбираются данные, посмотрите на это: https://streamable.com/kjis2

1 Ответ

1 голос
/ 30 января 2020

В конечном счете, не зная, какая часть вашего кода работает медленно (и сколько данных вы на самом деле загружаете), трудно дать конкретный совет. Похоже, вы загружаете 100 000 строк из таблицы. Это потенциально много данных, особенно если эти строки сами по себе большие.

Несколько вещей, которые нужно попробовать:

  • Добавьте некоторые инструменты для измерения производительности вокруг кусков кода, чтобы выяснить, что работает медленно. Это может быть так же просто, как просто вызвать time.time() до и после фрагмента кода и вывести разницу между двумя значениями:
import contextlib
import time
import pandas as pd
import streamlit as st


@contextlib.contextmanager
def profile(name):
    start_time = time.time()
    yield  # <-- your code will execute here
    total_time = time.time() - start_time
    print("%s: %.4f ms" % (name, total_time * 1000.0))

with profile("load_data"):
    df = pd.read_excel('materials.xlsx',nrows=100000)

with profile("create_multiselect"):
    species = st.multiselect('SELECT THE MATERIAL', df['Name'])

with profile("filter_on_name"):
    new_df = df[(df['Name'].isin(species))]
  • Измените аннотацию @st.cache на @st.cache(allow_output_mutation=True). Это позволит Streamlit избежать хэширования выходных данных функции (это гигантский c фрейм данных, который может занять некоторое время до ha sh).
  • Можно ли загружать меньше строк одновременно?
  • В качестве альтернативы, вы можете избежать загрузки всех данных, которые в каждой из этих строк? (Вам нужен, например, столбец «Синонимы»?) pandas.read_excel принимает параметр usecols, который позволяет ограничивать анализируемые столбцы.
  • Если вам нужны все эти данные, загруженные, не могли бы вы хранить его таким образом, чтобы обеспечить более быструю фильтрацию? Например, похоже, что pandas может взаимодействовать с SQLite. Не могли бы вы загрузить свои данные Excel в базу данных SQLite один раз, когда приложение запускается впервые, а затем выполнить запросы к этой базе данных, а не к DataFrame?
...