Как избежать ошибки «Слишком много открытых файлов» при использовании root .daskframes для создания daskframe из множества ROOT файлов - PullRequest
1 голос
/ 12 февраля 2020

Я хотел попробовать использовать root, чтобы прочитать несколько root файлов с плоскими ROOT NTupels в рамку стола. 214 файлов, 500 КБ каждый, около 8000 строк и 16 столбцов / переменных в каждом. Они легко помещаются в фрейм данных pandas в памяти, но я пытаюсь изучить dask (и выше root, работавший только с root_ pandas ранее), так как я ожидаю больших наборов данных в будущем.

Так что я подумал, что uproot.daskframes(list_of_paths, flatten=True) будет инструментом для чтения файлов в рамку стола. Создавать фреймворки приятно, но вычисляя его в следующей Too many open files ошибке: https://pastebin.com/mfHgB16Q Когда я ограничиваю файлы, например, до 100, это вычисление работает, но медленно (30 секунд), на нескольких файлах это не проблема. Когда я использую 100 файлов и увеличиваю корзину (например, 100 МБ), чтобы увеличить скорость, я получаю RecursionError: https://pastebin.com/xTHa1Wav

Мое собственное решение состояло в том, чтобы просто создать обычный pandas Фреймы данных с выкорчевыванием, задерживают создание и используют dask для создания их объединения, что хорошо работает для меня и приводит к более быстрым вычислениям, чем uproot.daskframes для большого количества файлов.

import uproot
from dask import delayed
import dask.dataframe as dd

def daskframe_from_rootfiles(path_list, treepath, branches=None):
    @delayed
    def get_df(file, treepath=None, branches=None):
        tree = uproot.open(file)[treepath]
        return tree.pandas.df(branches=branches)

    dfs = [get_df(path, treepath, branches=branches) for path in path_list]
    daskframe = dd.from_delayed(dfs)
    return daskframe

Преимущество отсрочка создания фрейма данных заключается в том, что я могу использовать dask для его распараллеливания.

Но я чувствую, что должен быть какой-то канонический способ и, возможно, что-то, чего мне не хватает, и, возможно, есть другие варианты, которые я должен использовать для daskframes или, может быть, я должен использовать какую-то другую функцию полностью для этого. Можете ли вы помочь мне с любыми идеями или лучшими практиками?

Ответы [ 2 ]

1 голос
/ 16 февраля 2020
    @delayed
    def get_df(file, treepath=None, branches=None):
        tree = uproot.open(file)[treepath]
        return tree.pandas.df(branches=branches)

Я предполагаю, что эта функция оставляет дескриптор открытого файла. Может быть есть какой-нибудь способ закрыть файл после открытия?

    @delayed
    def get_df(filename, treepath=None, branches=None):
        file = uproot.open(filename)
        tree = file[treepath]
        df = tree.pandas.df(branches=branches)
        file.close()  # does something like this exist?
        return df
1 голос
/ 12 февраля 2020

Комментарий Джима Пиварски подтверждает, что с моим подходом все в порядке и что я не совсем ошибаюсь. Поскольку он - разработчик, я не ожидаю гораздо более сложных ответов, поэтому я отмечу это как устаревшие.

Редактировать : я не могу пометить свой собственный ответ как решение пока не прошло 2 дня, поэтому я подожду до тех пор, пока кто-нибудь еще не отправит ответ.

...