Python: создать кадр данных pandas из нескольких csv.gz, извлекающих CSV только указанные столбцы (дубликаты)

Это сработало для меня, хотя я не уверен, что он более эффективен, чем другие предложения.

rollForward <- function(x){
  curr <- 0
  for (i in 1:length(x)){
    if (is.na(x[i])){
      x[i] <- curr
    }
    else{
      curr <- x[i]
    }
  }
  return(x)
}
191
задан Andy Hayden 20 December 2015 в 08:25
поделиться

8 ответов

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

path =r'C:\DRO\DCL_rawdata_files' # use your path
allFiles = glob.glob(path + "/*.csv")
frame = pd.DataFrame()
list_ = []
for file_ in allFiles:
    df = pd.read_csv(file_,index_col=None, header=0)
    list_.append(df)
frame = pd.concat(list_)
199
ответ дан ppaulojr 18 August 2018 в 09:52
поделиться
  • 1
    Какова цель начального frame = pd.DataFrame()? – FooBar 17 September 2014 в 16:03
  • 2
    Я думаю, вы должны добавить & nbsp; ignore_index = True & quot; to pd.concat (список) – stupidbodo 15 November 2014 в 04:44
  • 3
    То же самое более кратким и, возможно, быстрее, так как оно не использует список: df = pd.concat((pd.read_csv(f) for f in all_files)) Кроме того, следует использовать os.path.join(path, "*.csv") вместо path + "/*.csv", что делает его независимым от ОС. – Sid 23 January 2016 в 01:41
  • 4
    @Sid уже делает этот ответ, так что нынешнее зверство может лишиться своего лидерства. – ivan_pozdeev 17 March 2016 в 23:56
  • 5
    @curtisp вы все равно можете сделать это с ответом Сида, просто используйте pandas.read_csv(f).assign(filename = foo) внутри генератора. assign вернет весь фрейм данных, включая новый столбец filename – C8H10N4O2 4 April 2017 в 20:50

Альтернатива ответам 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
157
ответ дан Community 18 August 2018 в 09:52
поделиться
  • 1
    @bongbang Использование скобок возвращает генератор вместо списка. – Sid 15 April 2016 в 18:45
  • 2
    @Sid вложенные parens для формирования генератора и обертывания аргументов функции являются избыточными, т. Е. Вы можете просто сделать pd.concat(pd.read_csv(f) for f in all_files). – Mike 21 June 2016 в 20:28
  • 3
    @Mike, что удивительно, не знал, редактируя мой ответ соответственно. – Sid 21 June 2016 в 20:31
  • 4
    @Sid вам нужно ignore_index = True, если только удача csv-файлы не имеют индексный столбец и этот индекс уникален для всех файлов. – max 7 July 2016 в 06:23
  • 5
    Я рекомендую использовать glob.iglob вместо glob.glob; Первый возвращает и итератор (вместо списка) . – toto_tico 2 August 2017 в 12:52
import glob, os    
df = pd.concat(map(pd.read_csv, glob.glob(os.path.join('', "my_files*.csv"))))
19
ответ дан Jose Antonio Martin H 18 August 2018 в 09:52
поделиться
  • 1
    Отличный один вкладыш, особенно полезный, если нет аргументов read_csv! – rafaelvalle 9 November 2017 в 20:38
  • 2
    Если, с другой стороны, необходимы аргументы, это можно сделать с помощью lambdas: df = pd.concat(map(lambda file: pd.read_csv(file, delim_whitespace=True), data_files)) – fiedl 11 April 2018 в 14:46

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

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

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

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

6
ответ дан Jouni K. Seppänen 18 August 2018 в 09:52
поделиться

Если несколько файлов csv заархивированы, вы можете использовать zip-файл для чтения всех и конкатенации, как показано ниже:

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)))
3
ответ дан leon 18 August 2018 в 09:52
поделиться
filepaths = ['data/d1.csv', 'data/d2.csv','data/d3.csv','data/d4.csv']
df = pd.concat(map(pd.read_csv, filepaths))
2
ответ дан robmsmt 18 August 2018 в 09:52
поделиться

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

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

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

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 ---
10
ответ дан SKG 18 August 2018 в 09:52
поделиться

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

import glob, os 
import pandas as pd

path = r'C:\user\your\path\**'
all_rec = glob.iglob(os.path.join(path, "*.csv"), recursive=True)     
dataframes = (pd.read_csv(f) for f in all_rec)
big_dataframe = pd.concat(dataframes, ignore_index=True)

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

4
ответ дан toto_tico 18 August 2018 в 09:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: