Jak mohu zrychlit import mnoho csv je při filtrování a přidávání souborů?

0

Otázka

Mám nějaké Python (3.8) kód, který má následující:

  1. Procházky adresáře a podadresáře daného cestu
  2. Najde všechny .csv soubory
  3. Najde všechny .csv soubory s Pct v souboru
  4. Připojí cestu a soubor
  5. Čte CSV
  6. Dodává názvem na df
  7. Concatonates všechny dfs spolu

Níže uvedený kód funguje, ale trvá dlouhou dobu (15 min) na spolknout všechny CSV - tam jsou 52,000 soubory. To by mohlo ve skutečnosti být dlouhá doba, ale chci snížit tento, stejně jako je to možné.

Můj současný pracovní kodex je níže:

start_dirctory='/home/ubuntu/Desktop/noise_paper/part_2/Noise/Data/'  # change this
df_result= None
#loop_number = 0

for path, dirs, files in os.walk(start_dirctory):
        for file in sorted(fnmatch.filter(files, '*.csv')): # find .csv files
            # print(file)
            if 'Pct' in file: # filter if contains 'Pct'
                # print('Pct = ', file)
                full_name=os.path.join(path, file) # make full file path
                df_tmp= pd.read_csv(full_name, header=None) # read file to df_tmp
                df_tmp['file']=os.path.basename(file) # df.file = file name
                if df_result is None:
                    df_result= df_tmp
                else:
                    df_result= pd.concat([df_result, df_tmp], axis='index', ignore_index=True)
                #print(full_name, 'imported')
                #loop_number = loop_number + 1
                #print('Loop number =', loop_number)

Inspirován tento příspěvek (glob najít soubory rekurzivně) a tento příspěvek (jak zrychlit import csvs), snažil jsem se snížit čas, který je zapotřebí, aby spolknout všechny údaje, ale nemůžu přijít na to, způsob, jak integrovat filer pouze názvy souborů, které obsahují 'Pct a pak přidat názvem na df. To nemusí být možné s kódem z těchto příkladů.

Co jsem zkoušel níže (neúplné):

%%time

import glob
import pandas as pd

df = pd.concat(
    [pd.read_csv(f, header=None)
     for f in glob.glob('/home/ubuntu/Desktop/noise_paper/part_2/Noise/Data/**/*.csv', recursive=True)
    ],
    axis='index', ignore_index=True
 )

Otázka

Existuje nějaký způsob, jak mohu snížit čas na čtení a spolknout CSV je v mém kódu výše?

Díky!!!

csv dataframe glob pandas
2021-11-23 16:36:56
1

Nejlepší odpověď

0

Podívejte se na následující řešení, a to předpokládá, že open-limit souborový systém je dostatečně vysoká, protože to bude vysílat každý soubor jeden po druhém, ale to se musí otevřít každý z nich číst hlavičky. V případech, kde soubory mají různé sloupce, dostanete nadmnožina z nich ve výsledném souboru:

from convtools import conversion as c
from convtools.contrib.tables import Table

files = sorted(
    os.path.join(path, file)
    for path, dirs, files in os.walk(start_dirctory)
    for file in files
    if "Pct" in file and file.endswith(".csv")
)

table = None
for file in files:
    table_ = Table.from_csv(file, header=True)  # assuming there's header
    if table is None:
        table = table_
    else:
        table.chain(table_)

# this will be an iterable of dicts, so consume with pandas or whatever
table.into_iter_rows(dict)  # or list, or tuple

# or just write the new file like:
# >>> table.into_csv("concatenated.csv")
# HOWEVER: into_* can only be used once, because Table
# cannot assume the incoming data stream can be read twice

Pokud jste si jisti, že všechny soubory mají stejné sloupce (jeden soubor je otevřený v čase):

upraven tak, aby přidat soubor, sloupec

def concat_files(files):
    for file in files:
        yield from Table.from_csv(file, header=True).update(
            file=file
        ).into_iter_rows(dict)

# this will be an iterable of dicts, so consume with pandas or whatever
concat_files(files)

P. S. samozřejmě můžete nahradit Table.from_csv standardní/ostatní čtenáře, ale tohle se přizpůsobí souboru, tak to je obecně rychleji na velké soubory.

2021-11-25 14:18:15

Děkuji!!! Všechny soubory mají přesně stejné sloupce (bez záhlaví sloupců). Jak mohu nejlépe přidat plným názvem (obsahuje data) na datovém jako csv je číst a bude to fungovat s vaším druhý návrh?
Cairan Van Rooyen

@CairanVanRooyen, prosím, viz výše -- aktualizoval jsem druhý. pro více info - convtools.readthedocs.io/en/latest/tables.html
Nikita Almakov

@CairanVanRooyen dejte mi vědět, jestli to funguje pro vás lepší, než původní řešení, jen jsem zvědavý
Nikita Almakov

nemohu získat navrhl kód spustit. Jsem stále "AssertionError: move_rows nazývá 2. čas" @ řádku "tabulky.řetěz(table_)"
Cairan Van Rooyen

@CairanVanRooyen to mám! věci, jako je table.into_iter_rows(dict) nebo table.into_csv("concatenated.csv") může být provedeno pouze jednou, protože to funguje s datového toku, takže nelze předpokládat, že je dovoleno, aby si to přečíst dvakrát, takže vybrat si jeden
Nikita Almakov

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................