python, pyTorch

python) csv 파일 읽어오기/수정하기/쓰기

zooyeonii 2021. 9. 7. 16:50

pycharm 패키지 설치 방법

File > Settings > Project > Project Interpreter > + 

if __name__ =='__main__': 뜻
'__name__이라는 변수의 값이 __main__이라면 아래의 코드를 실행하라.'

이 조건문은, 직접 실행시켰을 때만 실행되길 원하는 코드들을 넣어주는 용이다.
예를 들어 모듈내에서만 사용하는 테스트용 코드를 넣어주게 되면, 실제 import될 때는 출력되지 않는다. 
모듈 테스트할 때 아주 유용하게 쓰고있다! 

리스트 추가하기 
(1) append 

>>> a = [1, 2, 3]
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> a.append([5,6])
>>> a
[1, 2, 3, 4, [5, 6]]

(2) extend (리스트 확장) 

>>> a = [1,2,3]
>>> a.extend([4,5])
>>> a
[1, 2, 3, 4, 5]
>>> b = [6, 7]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6, 7]

 

1. csv 읽어오기

csv --> node embedding matrix로 변환하기 

def read_from_file_to_embed(filepath):
    nodes_feature = []
    with open(filepath, 'r', newline='', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            row = list(map(int, row))
            nodes_feature.append(row)
        print(nodes_feature)

(i) python에서 \ufeff 가 읽히는 문제
첫번째 column에 \ufeff 가 붙는 문제가 생김. 행렬 요소를 int 형변환할 때 에러가 발생함. 
file open 할 때 with open(filepath, 'r', newline='', encoding='utf-8') 에서 encoding argument 를 'utf-8-sig'로 변환하면 해결된다. 
\ufeff 는 해당 file이 어떤 문자열로 코딩되었는지를 의미하는 식별자이다. utf-8-signature 라는 인코딩 방식을 넘겨주면, 앞의 식별자(파일의 메타정보)를 무시하게 된다. 

(ii) 리스트 문자열을 int 형변환 
csv 파일의 각 row를 int형변환 한 후 행렬에 추가하려고 한다. 
row는 리스트 형식이고, ['1', '0', '-1'] --> [1, 0, -1] 로 바꿔주려고 한다. 

>>> row_list = list(map(int, row_list))

(iii) csv 의 header 건너뛰기 
ValueError: could not convert string to float: 'peer_id' --> (ii)에서 row 마다 int 형변환할 때 에러가 발생하는 것은 헤더가 문자열이기 때문인데, 굳이 헤더를 삭제하지 않고 next()를 사용하면 간편하다. 헤더를 건너뛰고 다음 행부터 시작할 수 있다. 

>>> reader = csv.reader(file)
>>> next(reader, None)

 

2. csv 파일 만들기 

구현할 기능 : 기존 csv파일의 값을 수정하여 새로운 csv 파일을 만든다. 

1) 행렬 요소 수정하기 (열마다 수정하기)

(i) 0또는 1로 random하게 변경하기 
randint(a, b) : 인자로 들어온 a, b 사이의 랜덤한 정수(int)를 반환한다. 
반환하는 x는 a,b를 포함한 범위이다.
따라서 randint(0,1) 를 사용한다. 

import random
def update_matrix(matrix):
    for i in range(len(matrix)):
        	matrix[i][6] = random.randint(0,1)

(ii) 난수 생성 확률 부여하기 
난수를 분포에따라, 또는 확률에 따라 생성되게 만들기. 
p 난수를 생성해서 0.7 이상이면 (30%의 확률로), 행렬의 7번째 atrribute element를 0또는 1로 바꾸게 된다. 

import random
def update_matrix(matrix):
    for i in range(len(matrix)):
    	p = random.random()
        if p>0.7:
        	matrix[i][6] = random.randint(0,1)

(iii) 행렬 --> csv 파일로 만들기 

csv 모듈을 사용해서 리스트를 csv로 쉽게 저장할 수 있다. 
csv.reader(), csv.writer() 는 row를 반복하는 iterable 객체를 반환한다. 

writerow는 1차원 리스트 row를 저장할 때 사용한다. (헤더 입력)
writerows는 2차원 리스트 row들을 저장할 때 사용한다. (행렬 입력) 

matrix_to_file의 filepath 인자는 새로저장되는 파일의 경로, matrix 는 csv파일로 옮길 2차원 리스트 데이터이다. 

def matrix_to_file(filepath, matrix):
    rows = matrix
    with open(filepath, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)
        writer.writerow(fields) #헤더 작성
        writer.writerows(rows) #행렬 입력