Импортируйте несколько файлов csv в pandas и объедините в один DataFrame

Я хотел бы прочитать несколько файлов csv из каталога в pandas и объединить их в один большой DataFrame. Однако я не смог понять это. Вот что я до сих пор:

import glob
import pandas as pd

# get data file names
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")

dfs = []
for filename in filenames:
    dfs.append(pd.read_csv(filename))

# Concatenate all data into one DataFrame
big_frame = pd.concat(dfs, ignore_index=True)

Я думаю, мне нужна помощь в цикле for.

Ответ 1

Если у вас одинаковые столбцы во всех ваших csv файлах, вы можете попробовать код ниже. Я добавил header=0 чтобы после прочтения csv первой строке можно было присвоить имена столбцов.

import pandas as pd
import glob

path = r'C:\DRO\DCL_rawdata_files' # use your path
all_files = glob.glob(path + "/*.csv")

li = []

for filename in all_files:
    df = pd.read_csv(filename, index_col=None, header=0)
    li.append(df)

frame = pd.concat(li, axis=0, ignore_index=True)

Ответ 2

Альтернатива ответ darindaCoder:

path = r'C:\DRO\DCL_rawdata_files'                     # use your path
all_files = glob.glob(os.path.join(path, "*.csv"))     # advisable to use os.path.join as this makes concatenation OS independent

df_from_each_file = (pd.read_csv(f) for f in all_files)
concatenated_df   = pd.concat(df_from_each_file, ignore_index=True)
# doesn't create a list, nor does it append to one

Ответ 3

import glob, os    
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('', "my_files*.csv"))))

Ответ 4

Библиотека Dask может читать данные из нескольких файлов:

>>> import dask.dataframe as dd
>>> df = dd.read_csv('data*.csv')

(Источник: http://dask.pydata.org/en/latest/examples/dataframe-csv.html).

Фреймы данных Dask реализуют подмножество API фреймов данных Pandas. Если все данные df.compute() в память, вы можете вызвать df.compute() чтобы преобразовать df.compute() данных в df.compute() Pandas.

Ответ 5

Почти все ответы здесь либо излишне сложны (сопоставление с шаблоном), либо полагаются на дополнительные сторонние библиотеки. Вы можете сделать это в 2 строки, используя все, что уже встроено в Pandas и python (все версии).

Для нескольких файлов - 1 вкладыш:

df = pd.concat(map(pd.read_csv, ['data/d1.csv', 'data/d2.csv','data/d3.csv']))

Для многих файлов:

from os import listdir

filepaths = [f for f in listdir("./data") if f.endswith('.csv')]
df = pd.concat(map(pd.read_csv, filepaths))

Эта строка панд, которая устанавливает df, использует 3 вещи:

  1. Карта Python (функция, итерируемая) отправляет в функцию (pd.read_csv()) итерацию (наш список), которая является каждым элементом csv в пути к файлам).
  2. Функция Panda read_csv() читает в каждом файле CSV как обычно.
  3. Panda concat() объединяет все это в одну переменную df.

Ответ 6

Изменить: я googled мой путь в fooobar.com/questions/45779/.... Однако в последнее время я нахожу более быстрым делать какие-либо манипуляции с помощью numpy, а затем назначать его один раз на dataframe, а не манипулировать самим фреймворком на итеративной основе и, похоже, тоже работает в этом решении.

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

Вы можете использовать numpy, чтобы действительно ускорить конкатенацию dataframe.

import os
import glob
import pandas as pd
import numpy as np

path = "my_dir_full_path"
allFiles = glob.glob(os.path.join(path,"*.csv"))


np_array_list = []
for file_ in allFiles:
    df = pd.read_csv(file_,index_col=None, header=0)
    np_array_list.append(df.as_matrix())

comb_np_array = np.vstack(np_array_list)
big_frame = pd.DataFrame(comb_np_array)

big_frame.columns = ["col1","col2"....]

Сроки:

total files :192
avg lines per file :8492
--approach 1 without numpy -- 8.248656988143921 seconds ---
total records old :1630571
--approach 2 with numpy -- 2.289292573928833 seconds ---

Ответ 7

Если вы хотите выполнить рекурсивный поиск (Python 3.5 или выше), вы можете сделать следующее:

from glob import iglob
import pandas as pd

path = r'C:\user\your\path\**\*.csv'

all_rec = iglob(path, recursive=True)     
dataframes = (pd.read_csv(f) for f in all_rec)
big_dataframe = pd.concat(dataframes, ignore_index=True)

Обратите внимание, что три последние строки могут быть выражены в одной строке:

df = pd.concat((pd.read_csv(f) for f in iglob(path, recursive=True)), ignore_index=True)

Вы можете найти документацию ** здесь. Также я использовал iglob вместо glob, так как он возвращает итератор вместо списка.



РЕДАКТИРОВАТЬ: Мультиплатформенная рекурсивная функция:

Вы можете обернуть вышеупомянутое в многоплатформенную функцию (Linux, Windows, Mac), так что вы можете сделать:

df = read_df_rec('C:\user\your\path', *.csv)

Вот функция:

from glob import iglob
from os.path import join
import pandas as pd

def read_df_rec(path, fn_regex=r'*.csv'):
    return pd.concat((pd.read_csv(f) for f in iglob(
        join(path, '**', fn_regex), recursive=True)), ignore_index=True)

Ответ 8

Если несколько CSV файлов заархивированы, вы можете использовать zipfile, чтобы прочитать все и объединить, как показано ниже:

import zipfile
import numpy as np
import pandas as pd

ziptrain = zipfile.ZipFile('yourpath/yourfile.zip')

train=[]

for f in range(0,len(ziptrain.namelist())):
    if (f == 0):
        train = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
    else:
        my_df = pd.read_csv(ziptrain.open(ziptrain.namelist()[f]))
        train = (pd.DataFrame(np.concatenate((train,my_df),axis=0), 
                          columns=list(my_df.columns.values)))

Ответ 9

Легко и быстро

Импортируйте два или более csv без необходимости составлять список имен.

import glob

df = pd.concat(map(pd.read_csv, glob.glob('data/*.csv')))

Ответ 10

Я нашел этот метод довольно элегантным.

import pandas as pd
import os

big_frame = pd.DataFrame()

for file in os.listdir():
    if file.endswith('.csv'):
        df = pd.read_csv(file)
        big_frame = big_frame.append(df, ignore_index=True)

Ответ 11

один лайнер, использующий map, но если вы хотите указать дополнительные аргументы, вы можете сделать:

import pandas as pd
import glob
import functools

df = pd.concat(map(functools.partial(pd.read_csv, sep='|', compressed=None), 
                    glob.glob("data/*.csv")))

Примечание: map сама по себе не позволяет вводить дополнительные аргументы.

Ответ 12

Еще один on-liner со списком, который позволяет использовать аргументы с read_csv.

df = pd.concat([pd.read_csv(f'dir/{f}') for f in os.listdir('dir') if f.endswith('.csv')])

Ответ 13

На основании @Sid хороший ответ.

Перед объединением вы можете загрузить CSV файлы в промежуточный словарь, который предоставляет доступ к каждому набору данных на основе имени файла (в форме dict_of_df['filename.csv']). Такой словарь может помочь вам выявить проблемы с разнородными форматами данных, например, когда имена столбцов не выровнены.

Импортируйте модули и найдите пути к файлам:

import os
import glob
import pandas
from collections import OrderedDict
path =r'C:\DRO\DCL_rawdata_files'
filenames = glob.glob(path + "/*.csv")

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

Загрузите CSV файлы в словарь. Затем объедините:

dict_of_df = OrderedDict((f, pandas.read_csv(f)) for f in filenames)
pandas.concat(dict_of_df, sort=True)

Ключи - это имена файлов f, а значения - содержимое фрейма данных CSV файлов. Вместо использования f в качестве ключа словаря, вы также можете использовать os.path.basename(f) или другие методы os.path, чтобы уменьшить размер ключа в словаре до только меньшей части, которая имеет отношение к делу.

Ответ 14

Альтернатива с использованием библиотеки pathlib (часто предпочтительнее, чем os.path).

Этот метод позволяет избежать многократного использования панд concat()/apped().

Из документации панд:
Стоит отметить, что concat() (и, следовательно, append()) создает полную копию данных, и что постоянное повторное использование этой функции может привести к значительному снижению производительности. Если вам нужно использовать операцию над несколькими наборами данных, используйте понимание списка.

import pandas as pd
from pathlib import Path

dir = Path("../relevant_directory")

df = (pd.read_csv(f) for f in dir.glob("*.csv"))
df = pd.concat(df)