HOWTO · NumPy
파이썬에서 CSV에 NumPy 배열 쓰기
이 튜토리얼은 csv 파일에 numpy 배열을 저장하는 방법을 보여줍니다.
이 페이지의 내용
숫자로 된 NumPy 배열을 쉼표로 구분된 텍스트로 저장하려면 numpy.savetxt()를 사용하세요. 배열을 DataFrame 작업 흐름에서 다뤄야 한다면 pandas를, 행을 직접 만들거나 사용자 지정해야 한다면 csv.writer를 선택하세요. CSV는 행과 열로 이루어진 형식이므로, 저장하기 전에 1차원 또는 고차원 배열을 행에 어떻게 대응시킬지 정해야 합니다.
예제에서는 정수 값으로 이루어진 작은 2차원 배열을 사용합니다. 각 방법은 헤더나 인덱스 없이 값만 저장합니다. 배열 예제에는 NumPy가 필요하고, pandas 예제에는 별도 패키지인 pandas가 필요합니다. 코드와 표시되는 출력은 원본 그대로 영어로 유지됩니다.
배열과 필요한 출력에 따라 방법 선택하기
숫자 배열을 단순한 구분자 텍스트 파일로 저장하려면 numpy.savetxt()가 기본 선택으로 적합합니다. delimiter로 구분자를 지정하고 fmt로 각 값을 어떤 형식으로 표현할지 정합니다. DataFrame 연산이나 열 이름이 필요하다면 pandas를 사용하세요. 행을 직접 처리하거나 Python의 CSV 인용 규칙을 적용해야 한다면 csv.writer를 선택하세요. 내장 writer는 값을 문자열로 이어 붙이는 방식보다 필드 안의 쉼표와 따옴표를 안전하게 처리합니다.
1차원 배열을 savetxt에 전달하면 열 벡터로 처리되어 값마다 한 줄씩 기록됩니다. 값을 CSV 한 행에 가로로 저장하려면 저장하기 전에 배열을 (1, -1) 형태로 바꾸세요. 아래 csv.writer 반복문은 2차원 배열을 전제로 하며, 반복할 때마다 얻는 row는 그 자체로 순회할 수 있어야 합니다. 1차원 입력을 한 행으로 쓰려면 writer.writerow(data)를 사용하세요. 값을 한 행에 하나씩 기록하려면 값을 반복하면서 writer.writerow([value])를 호출하면 됩니다. CSV 파일에는 3차원 데이터를 그대로 표현하는 방법이 없습니다. 3차원 배열을 행과 열로 재구성하거나 평탄화하되, 읽는 쪽에서 원래 배열을 복원할 수 있도록 순서를 정하세요. 평탄화가 데이터 배치를 의도치 않게 결정하게 두지 마세요.
numpy.savetxt()로 NumPy 배열 저장하기
예제의 정수 값에는 '%d' 형식이 적합합니다. 부동소수점 데이터에서 소수점 이하 세 자릿수면 충분하다면 '%.3f' 같은 형식을 선택할 수 있습니다. 형식 지정으로 값이 반올림될 수 있으므로 보존해야 하는 데이터에 맞춰 정밀도를 정하세요. 수신 도구가 다른 구분자를 요구한다면 ';' 또는 '\t'를 delimiter로 지정할 수 있습니다.
이 예제를 실행하세요:
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
from pathlib import Path
from tempfile import TemporaryDirectory
import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
path = Path(directory) / "array.csv"
np.savetxt(path, data, delimiter=",", fmt="%d")
print(path.read_text(), end="")
1,2,3
4,5,6
pandas로 NumPy 배열 저장하기
배열을 DataFrame으로 변환한 다음 to_csv()를 호출하세요. 기본 설정에서 pandas는 DataFrame 인덱스와 열 이름을 기록합니다. 파일에 배열 값만 담으려면 index=False와 header=False를 지정하세요. 받는 사람에게 의미 있는 레이블이라면 해당 필드를 유지하거나 직접 지정하면 됩니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
from pathlib import Path
from tempfile import TemporaryDirectory
import numpy as np
import pandas as pd
data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
path = Path(directory) / "array.csv"
pd.DataFrame(data).to_csv(path, index=False, header=False)
print(path.read_text(), end="")
1,2,3
4,5,6
Python의 csv 모듈로 행 쓰기
csv.writer는 순회 가능한 각 행을 기록하고 CSV 문법에 따라 필요한 필드를 이스케이프합니다. 파일을 newline=""로 여세요. 그러면 CSV 모듈이 줄바꿈 문자를 관리하며, 줄바꿈 변환이 적용되는 플랫폼에서 빈 줄이 추가되는 것을 방지합니다. 다음 예제는 배열의 행을 그대로 사용합니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
from pathlib import Path
from tempfile import TemporaryDirectory
import csv
import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
with TemporaryDirectory() as directory:
path = Path(directory) / "array.csv"
with path.open("w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
for row in data:
writer.writerow(row)
print(path.read_text(), end="")
1,2,3
4,5,6
행을 덧붙이려면 대상 파일을 추가 모드("a")로 열고 새 행만 기록하세요. 새 행의 열 순서와 개수가 기존 파일과 맞는지 확인해야 합니다. 추가 모드는 파일을 검증하거나 헤더를 대신 추가해 주지 않습니다. 1차원 입력은 한 행으로 볼지, 행마다 값 하나를 둘지 정한 다음 그에 맞게 배열 형태를 바꾸거나 감싸세요.
ndarray.tofile()의 한계 이해하기
ndarray.tofile()은 배열 메서드이지만 CSV writer는 아닙니다. 배열 요소를 평탄화된 순서로 기록하므로 원래 모양이나 행과 열 구조를 보존하지 않습니다. 쉼표 구분자를 사용해 구분자 텍스트를 만들 수는 있지만, 파일만으로는 원래 차원을 알 수 없습니다. 출력 표현은 선택한 형식에도 좌우됩니다. 한 줄로 기록되었다는 사실만으로 숫자 정밀도가 손실되었다고 볼 수는 없습니다. 명시적인 CSV 배치가 필요하다면 savetxt, pandas 또는 csv.writer를 사용하세요.
간단한 데이터에만 CSV 텍스트 직접 작성하기
단순한 숫자 값으로 이루어진 작고 형태가 분명한 2차원 배열이라면 Python 문자열 형식 지정을 사용해 행을 직접 만들 수 있습니다. 이 방법은 배열의 모양과 값이 일반 텍스트로 표현하기에 적합하다고 가정합니다. join으로 전체 결과를 한 번에 만들면 출력 크기에 비례하는 메모리를 사용합니다. 또한 값을 수동으로 이어 붙이는 방식은 쉼표, 따옴표 또는 줄바꿈이 포함된 값을 CSV 규칙에 맞게 처리하지 않습니다. 일반적인 데이터나 텍스트 필드에는 csv.writer를 사용하세요.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
from pathlib import Path
from tempfile import TemporaryDirectory
data = [[1, 2, 3], [4, 5, 6]]
with TemporaryDirectory() as directory:
path = Path(directory) / "array.csv"
content = "\n".join(",".join(str(value) for value in row) for row in data)
path.write_text(content + "\n", encoding="utf-8")
print(path.read_text(), end="")
1,2,3
4,5,6