Programing

여러 CSV 파일을 팬더로 가져오고 하나의 DataFrame으로 연결

lottogame 2020. 3. 13. 08:14
반응형

여러 CSV 파일을 팬더로 가져오고 하나의 DataFrame으로 연결


디렉토리에서 팬더로 여러 CSV 파일을 읽고 하나의 큰 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 루프 내에서 도움이 필요하십니까 ???


모든 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)

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

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

Dask 라이브러리는 여러 파일에서 데이터 프레임을 읽을 수 있습니다.

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

(출처 : http://dask.pydata.org/en/latest/examples/dataframe-csv.html )

Dask 데이터 프레임은 Pandas 데이터 프레임 API의 하위 집합을 구현합니다. 모든 데이터가 메모리에 맞는 경우 호출df.compute() 하여 데이터 프레임을 Pandas 데이터 프레임으로 변환 할 수 있습니다 .


여기의 거의 모든 답변은 불필요하게 복잡하거나 (글로브 패턴 일치) 추가 타사 라이브러리에 의존합니다. Pandas와 python (모든 버전)에 이미 내장되어있는 모든 것을 사용하여 2 줄로이를 수행 할 수 있습니다.

몇 가지 파일-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. 파이썬의 맵 (함수, 반복 가능) 은 함수 ( ) 에게 pd.read_csv()파일 경로의 모든 csv 요소 인 반복 가능 (우리의 목록)을 보냅니다 .
  2. Panda의 read_csv () 함수는 각 CSV 파일을 정상적으로 읽습니다.
  3. Panda의 concat () 은이 모든 것을 하나의 df 변수로 가져옵니다.

편집 : 나는 https://stackoverflow.com/a/21232849/186078에 갔다 . 그러나 최근에 numpy를 사용하여 조작을 수행 한 다음 반복적으로 데이터 프레임 자체를 조작하는 대신 데이터 프레임에 한 번 할당하는 것이 더 빠르며이 솔루션에서도 작동하는 것으로 보입니다.

이 페이지를 방문하는 사람이이 접근법을 고려하기를 진심으로 원하지만이 거대한 코드를 주석으로 첨부하여 읽기 어렵게 만들고 싶지는 않습니다.

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 ---

재귀 적 으로 검색 하려면 ( 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)

여러 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)))

쉽고 빠른

csv이름 목록을 만들지 않고 둘 이상의를 가져 옵니다.

import glob

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

이 방법이 매우 우아하다는 것을 알았습니다.

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)

하나의 라이너를 사용 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그 자체로는 추가 인수를 제공 할 수 없습니다.


read_csv와 함께 인수를 사용할 수있는 목록 이해 기능을 갖춘 또 다른 라이너.

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

@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 메소드를 사용하여 사전의 키 크기를 관련있는 작은 부분으로 만 줄일 수 있습니다.


pathlib라이브러리를 사용하는 대안 (종종 선호 os.path).

이 방법은 pandas 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)

참고 URL : https://stackoverflow.com/questions/20906474/import-multiple-csv-files-into-pandas-and-concatenate-into-one-dataframe

반응형