본문으로 바로가기
반응형
이글은 Phtyon 3를 기반으로 작성되었습니다.

파이썬은 대부분 그 자체의 사용용도 보다는 Data를 분석하는데 많이 쓰입니다. txt 타입의 형태도 많이 쓰기는 하지만 DB에서 csv로 export한다던가, excel로 작성된 데이터도 많이 다루기 때문에 이 파일을 파이썬에서 import하고 가공하는 방법에 대하여 얘기해 봅니다.

csv 파일 로드

import csv
my_file = open('albumlist.csv', 'r') # 읽기 모드로 열기
reader = csv.DictReader(my_file)

my_file.close() #파일닫기

먼저 csv를 import해야 합니다. 그리고 open 함수와 open mode를 지정하여 파일을 읽습니다.

  • r: 읽기전용 (기본모드)
  • w: 쓰기전용 (기존파일을 override 하거나, 새파일을 생성)
  • r+: 읽기 및 쓰기 가능한 상태로 open

이때  csv.DicReader()는 csv를 dictionary 형태로 읽겠다는 의미 입니다. 즉 엑셀의 row 하나당 dict 형태로 column명:value 형태로 값을 반환 합니다.

이때 open한 파일은 반드시 닫아야 하기 때문에 close()함수를 호출해야 합니다. close 함수의 누락을 방지하기 위해서 아래와 같은 with open 구문을 이용하면 사용이 완료된후 자동으로 close()가 수행 됩니다.

import csv
with open('albumlist.csv', 'r') as csvfile:
    reader = csv.DictReader(csvfile)
    
    print(type(reader))
    print(reader.fieldnames)

 이때의 결과는 

위와 같이 출력 됩니다.

반응형

filednames는 엑셀의 상단 제목( columns)를 출력합니다.  실제 albumlist.csv 파일은 아래와 같은 내용을 담고 있습니다.

DicReader의 사용

csv.DicReader로 읽어온 데이터는 아래와 같이 출력해볼 수 있습니다.

with open('albumlist.csv', 'r') as csvfile:
    reader = csv.DictReader(csvfile) #DicReader는 한번 for loop을 하면 사라진다. ->메모리에 저장 안함.
    
    for row in reader:
        print(row)

for문으로 반복해서 불러들일이면 아래와 같은 dict 형태로 가져왔음을 확인할 수 있습니다.

여기서 중요한점은 DicReader는 읽은 데이터를 메모리에 담아두지 않습니다. 따라서 한번 iteration을 돌면 다시 iteration을 돌면서 데이터를 뽑아낼 수 없습니다. 따라서 계속 데이터를 재활용 해야 한다면 아래와같이 list를 하나 만들어 담아두고 쓰도록 합니다.

with open('albumlist.csv', 'r') as csvfile:
    reader = csv.DictReader(csvfile) #DicReader는 한번 for loop을 하면 사라진다. ->메모리에 저장 안함.
    
    albums = []
    for row in reader:
        albums.append(row)
    
    print("num of albums", len(albums))

len으로 list를 출력해 보면 위와같이 나옵니다. 즉. albums 리스트를 만들어 담아놓은 데이터의 row가 총 500개는 얘기입니다.

albums에 담아 두었으니 이제 해당 list를 통해서 여러가지 작업을 진행할 수 있습니다.

albums_1974 = [row for row in albums if row["Year"] == "1974"]
print(len(albums_1974))

Year column의 값이 1974년인 row만 flitering하여 alumbs_1974에 담고, 개수를 출력하는 구문 입니다.

Casting

Year라는 값을 숫자type으로 변형하려면 아래와 같은 방법으로 casting 할 수 있습니다.

release_years = [int(row["Year"]) for row in albums]

다만 Year column에 int로 변경 불가한 값이 들어 있다면 오류가 발생할 수 있습니다.

컬럼에 nineteen seventy three라는 값이 있기 떄문에 casting중에 오류를 뱉습니다. 따라서 casting시에는 validation check 이후 호출하도록 아래와 같이 수정해 볼수 있습니다.

def isValidYear(string):
    try:
        year = int(string) # int로 casting
    except ValueError:
        return False
    else:
        return True
        
release_years = [int(row["Year"]) for row in albums if(isValidYear(row["Year"]))]
print(release_years)

 

다음 포스팅에서는 좀더 database처럼 2차원 배열로 만들어 쓸수 있는 pandas에 대해서 다뤄 보도록 하겠습니다.

반응형