Индикатор выполнения Pandas to_csv с tqdm

#python #pandas #tqdm

#python #pandas #tqdm

Вопрос:

Как следует из названия, я пытаюсь отобразить индикатор выполнения во время выполнения pandas.to_csv .
У меня есть следующий скрипт:

 def filter_pileup(pileup, output, lists):
    tqdm.pandas(desc='Reading, filtering, exporting', bar_format=BAR_DEFAULT_VIEW)
    # Reading files
    pileup_df = pd.read_csv(pileup, 't', header=None).progress_apply(lambda x: x)
    lists_df = pd.read_csv(lists, 't', header=None).progress_apply(lambda x: x)
    # Filtering pileup
    intersection = pd.merge(pileup_df, lists_df, on=[0, 1]).progress_apply(lambda x: x)
    intersection.columns = [i for i in range(len(intersection.columns))]
    intersection = intersection.loc[:, 0:5]
    # Exporting filtered pileup
    intersection.to_csv(output, header=None, index=None, sep='t')
  

В первых нескольких строках я нашел способ интегрировать индикатор выполнения, но этот метод не работает для последней строки, как я могу этого добиться?

Комментарии:

1. Действительно хакерским способом вы можете создать класс-оболочку, наследующий от io.TextIOBase around output , который передает .write вызовы через output , обновляя индикатор выполнения. Не рекомендовал бы, поэтому я не публикую его в качестве ответа.

2. Вы нашли решение? Я был бы признателен, если бы вы могли опубликовать его в качестве ответа 🙂

3. @Sierox Я не нашел решения для этой точной проблемы, но в конце концов вместо pandas я использовал модуль dask, у которого есть индикатор выполнения в самом модуле под dask.diagnostics

Ответ №1:

Вы можете разделить фрейм данных на фрагменты n строк и сохранить фрейм данных в формате csv фрагмент за фрагментом, используя mode= ‘w’ для первой строки и mode =»a» для остальных:

Пример:

 import numpy as np
import pandas as pd
from tqdm import tqdm

df = pd.DataFrame(data=[i for i in range(0, 10000000)], columns = ["integer"])

print(df.head(10))

chunks = np.array_split(df.index, 100) # split into 100 chunks

for chunck, subset in enumerate(tqdm(chunks)):
    if chunck == 0: # first row
        df.loc[subset].to_csv('data.csv', mode='w', index=True)
    else:
        df.loc[subset].to_csv('data.csv', header=None, mode='a', index=True)
  

Вывод:

     integer
0        0
1        1
2        2
3        3
4        4
5        5
6        6
7        7
8        8
9        9

100%|██████████| 100/100 [00:12<00:00,  8.12it/s]
  

Комментарии:

1. array_split Функция принимает количество массивов для создания. Комментарий должен быть # split into 100 chunks , см. Также numpy.org/doc/stable/reference/generated/numpy.array_split.html