J'ai rencontré une scène où je voulais lire plusieurs fichiers csv stockés dans plusieurs fichiers zip sous un certain dossier à la fois, j'ai donc pris une note.
Lorsque la structure des dossiers est comme ça, je veux lire les fichiers csv dans chaque fichier zip à la fois et les stocker dans la liste.
input/
┣ zip_files/
┃ ┣ test1.zip/
┃ ┃ ┣ test1_1.csv
┃ ┃ ┣ test1_2.csv
┃ ┃ ...
┃ ┣ test2.zip/
┃ ┃ ┣ test2_1.csv
┃ ┃ ┣ test2_2.csv
┃ ...
Vous pouvez accéder aux fichiers à l'intérieur sans ouvrir le zip avec les fonctions unzip et unz. Je voulais l'ajouter à la liste en tant qu'addition de python, mais je n'étais pas sûr, alors j'ai compromis ci-dessous.
library(tidyverse)
library(data.table)
zip_list <- list.files("zip_files")
# function of read csv files in zip files
get_csv <- function(zip_list){
csv_list <- list()
zip_lists <- list()
# Loop through the list of files
for(j in 1:length(zip_list)) {
# Create list of files
file <- unzip(paste0("zip_files/", zip_list[j]), list = TRUE)
for(i in 1:length(file)){
# If a file is a csv file, unzip it and read the data
if(grepl("csv", file[i,1])) {
print(paste0('reading following file...', file[i,1]))
csv_files <- read_csv(unz(paste0("zip_files/", zip_list[j]), file[i,1]),
col_names=TRUE)
########################
# Add Some process.
########################
csv_list[[i]] <- csv_files
zip_lists[[j]] <- csv_list
}
}
}
return(zip_lists)
}
system.time(csvs <- get_csv(zip_list))
Vous pouvez accéder à l'intérieur sans décompresser le fichier zip avec le module zipfile. enumerate renvoie l'index et l'élément de l'objet à transformer par l'instruction for, ce qui est pratique lors de l'ajout d'un traitement. (Dans l'exemple ci-dessous, c'est pareil même s'il n'est pas utilisé)
import os
import zipfile
import glob
import pandas as pd
import time
df_list = list()
start = time.time()
for i, zips in enumerate(zip_list):
zip_f = zipfile.ZipFile(zips)
file_list = zip_f.namelist() # file names of csv files in zip
for j, files in enumerate(file_list):
print('reading following file...' + zips + '/' + files)
df = pd.read_csv(zip_f.open(files))
########################
# Add Some process.
# If use i and j too.
########################
df_list.append(df)
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
Recommended Posts