DictReader와 DictWriter를 사용하여 Python에서 CSV를 유연하게 처리

31765 단어 pythoncsvtutorial

The code in this article is also available in a public Github repo here.


Python은 데이터 논쟁에 적합하다.한 시스템에서 데이터를 추출하여 변환한 다음 다른 시스템(ETL)에 로드하는 것을 발견하셨습니까?그러면 CSV 파일을 한두 번 만났을 수도 있습니다.
CSV 파일은 일반적으로 대형 간단한 데이터 테이블을 불러오는 도구로 사용된다.Python has built-in CSV handling capability . 본고에서 우리는 파이톤의 csv.DictReadercsv.DictWriter을 사용하여 CSV 파일을 읽고 저장하는 유연한 방법을 모색할 것이다.

유연한 현장 처리
이 예에서, 나는 flexible를 사용하여 동적 열을 처리할 때 처리 프로그램의 탄력을 나타낸다.
변경 사항(예: 제품 업그레이드)에서 추출한 시스템에서 CSV 내보내기 파일에 필드를 추가하는 장면을 상상해 보십시오.그리고 끝이 아니라 중간이나 맨 왼쪽에 있는 열로 쉽게 추가할 수 있다.읊다, 읊조리다파이톤에서 이런 이동 목표를 우아하게 처리할 수 있는 처리 프로그램을 만들 수 있는 방법이 있습니까?
그래.

CSV 예
테이블 데이터(즉, 테이블의 데이터)를 살펴보겠습니다.
성.
성함
중명
역할
학교.
등급
헤르만
프레스턴
엘리엇
선생.
남구
룬돌프
페니건
브레론
학생.
동구
12
덮다
이스턴
페르난도
학생.
남구
7
칸프
로건
김슬리
선생.
남구
위 CSV 형식의 데이터는 머리글 행과 함께 다음과 같이 표시되어야 합니다.
Last name,First name,Middle name,Role,School,Grade
Herman,Preston,Elliott,Teacher,Southside,
Randolph,Finnegan,Braylon,Student,Eastside,12
Hood,Easton,Fernando,Student,Southside,7
Kemp,Logan,Kinsley,Teacher,Southside,
원하는 경우 download the above CSV sample here으로 전화하십시오.
이 내용을 현재 작업 디렉터리에 있는 sample.csv이라는 파일에 넣으십시오.너도 본문 clone the repo을 읽을 수 있고 이런 방식으로 계속 읽을 수 있다.

CSV 파일 로드
Python에서 CSV 파일을 로드하려면 먼저 파일을 엽니다.파이톤의 파일 처리에 있어서 편리하고 유연하기 위해 나는 항상 pathlib을 즐겨 사용한다.
from pathlib import Path

inpath = Path("sample.csv")
위에서 간단하게 inpath 변수를 분배하여 우리의 파일을 가리켰다.
파일을 열어 읽기와 쓰기를 하는 편리하고 안전한 방법은 with 문장을 사용하는 것이다. 왜냐하면 '상하문 관리자' 를 만들어서 파일을 처리하고 완성되면 자동으로 닫을 수 있기 때문이다.다시 말하면 파이톤은 당신이 정리한 후에 기꺼이 정리할 것입니다.
with inpath.open("r") as infile:
    contents = infile.read()
이것은 파일의 전체 내용을 contents 변수에 불러온 다음 파일을 닫는 데 매우 유효합니다.우리는 'r' 모드로 파일을 읽을 계획이라고 밝혔다. ('w' 모드로 쓰는 것이 아니라.)

Admittedly, it would be even easier to write contents = inpath.read_text(). However, that would not have demonstrated with and open very well! And it isn't relevant for CSV handling, as you will see in the next sentence.


그러나 Python의 CSV 처리를 사용하면 파일 내용을 메모리에 불러올 필요가 없습니다.반대로 우리는 파일 핸들(위의 예시에서 infile)을 csv.DictReader에 전달한다.이것은 우리에게 고급 줄 해석 능력과 줄마다 파일을 불러오는 데 절약할 수 있는 메모리를 제공했다.
import csv
from pathlib import Path


inpath = Path("sample.csv")

with inpath.open("r", newline="", encoding="utf-8-sig") as infile:
    reader = csv.DictReader(infile)
    for row in reader:
        fullname= f"{row['First name']} {row['Middle name']} {row['Last name']}"
        print(fullname)
download the above code from here을 선택할 수도 있습니다.
위 코드를 simplereader.py이라는 파일에 저장하면 sample.csv과 같은 디렉토리에 있다고 가정하면 다음과 같은 작업을 수행할 수 있습니다.
$ python simplereader.py
Preston Elliott Herman
Finnegan Braylon Randolph
Easton Fernando Hood
Logan Kinsley Kemp
python simplereader.py 명령은 파이톤으로 작성한 스크립트를 실행합니다.

Depending on your system, you may need to use python3 instead of python. If python -V doesn't show something like Python 3.8.5 (the 3 is the important part!), and python3 -V does, then use the latter instead.


상술한 코드 중의 두 가지 새로운 내용은 주의할 만하다.파일을 열 때, 우리는 일반 줄 바꾸기 지원을 사용하기 위해 newline=""을 지정합니다.그 원리는 매우 복잡하기 때문에 우리는 서로 다른 운영체제가 줄 바꾸기를 처리하는 여러 방식을 깊이 연구하지 않을 것이다.CSV 처리를 위해 파일을 열 때는 일반적으로 newline=""을 지정해야 합니다.자세한 내용은 read about newline parameter in the offical docs으로 전화하십시오.
두 번째는 문자 인코딩이다.

문자 인코딩의 중요성
완곡하게 말하자면, 우리는 문자 인코딩을 감히 소홀히 할 수 없다.이것은 상술한 상황에만 적용된다. 왜냐하면 우리의 sample.csv은 마침 ASCII글자이기 때문이다.우리가'미로시'와'마리아'라는 이름을 붙이면, 특히张伟, 그리고 우리는 더욱 자세하게 생각해야 한다.글씨체로 말하자면 조심해야 한다. 왜냐하면 이러한 선택은 실제 인물에 대한 관심과 실제 데이터와 사용자 인터페이스의 질과 기능을 전달하기 때문이다.
"나는 문자 인코딩을 사용할 줄 모른다"고 말하는 것은 기술적으로는 불가능할 뿐만 아니라 "왜 모든 사람이 미국말을 할 수 없느냐"고 불평하는 것과 유사하다.
위의 예에서 utf-8-sig을 지정했는데 일반적인 UTF-8 텍스트 인코딩과 UTF-8 인코딩이 메시지(BOM) 문자로 표시된 파일, 예를 들어 Microsoft Excel의 새로운'CSV UTF-8'형식을 열고 번역할 것입니다.
파일이 오래된 Microsoft Excel CSV 형식으로 저장되기 때문에 문자 인코딩은 라틴 인코딩의 일종인 "cp1252"일 수 있습니다.
한마디로 문자 인코딩을 항상 지정합니다.만들지 않은 CSV 파일의 인코딩을 모르면 인코딩 옵션은'cp1252','utf-8','utf-8-sig','iso-8859-1'또는 다른 것일 수 있습니다.너는 아마 실험을 진행해야 할 것이다.
필요할 때 파이톤 라이브러리(예를 들어 chardet 또는 속도가 더 빠른 cchardet)를 사용하여 파일의 문자 인코딩을 자동으로 감지할 수 있습니다.그러나 이것은 다른 문장을 쓸 만하다.

CSV 파일 작성
새 CSV 파일을 만드는 것은 읽는 것과 유사합니다. with 문구를 사용하여 상하문 관리자에서 이 파일을 열기 때문에 문자 인코딩에 주의해야 합니다.그러나 이번에 우리는 다음과 같이 할 것이다.
  • 파일을 "w"모드로 열어
  • 에 쓰기
  • 인스턴스화 csv.DictWriter 시 입력 필드(열) 이름
  • 은 모든 행
  • 에 쓰기 전에 제목을 writeheader()으로 씁니다.
  • 새 사전
    다음 코드는 이러한 내용을 보여 줍니다.
    import csv
    from pathlib import Path
    
    
    outpath = Path("out/output.csv")
    outpath.parent.mkdir(exist_ok=True)  # ensure the "out" directory exists
    
    with outpath.open("w", newline="", encoding="utf-8-sig") as outfile:
        writer = csv.DictWriter(outfile, ["First", "Last"])
        writer.writeheader()
        new_row = {"First": "Jane", "Last": "Smith"}
        writer.writerow(new_row)
    
    download the above code here을 선택할 수도 있습니다.
    (utf-8-sig을 인코딩으로 사용하기 때문에 Microsoft Excel에서 UTF-8 인코딩된 CSV로 열 수 있습니다. 파일 시작 부분에 BOM 문자를 사용하지 않으려면 인코딩을 utf-8으로 변경할 수 있습니다.)
    상기 내용을 simplewriter.py으로 저장하고 python simplewriter.py을 사용하면 out 디렉터리가 있어야 하며 그 중에는 output.csv이 포함되어 있어야 한다.파일에는 머리글과 데이터 행 두 줄이 있습니다.
    포스터
    최후
    간략하다
    스미스
    다음 줄을 추가하려면 새 사전을 사용하여 writer.writerow()을 다시 호출할 수 있습니다.

    다른 파일을 쓰는 동안 파일을 읽어서 데이터를 변환합니다.
    CSV 파일을 처리할 때, 나는 항상 한 CSV 파일에서 데이터를 추출하여 어떤 방식으로 변환하고, 즉각 두 번째 CSV 파일을 만들고, 이 파일을 재구성/변경/정리한 데이터로 채우려고 하는 것을 발견했다.나는 간단하고 효율적이며 안전한 방식으로 이 일을 하는 것을 좋아한다.
    솔루션: 하나의 with 문에서 두 개의 파일(컨텍스트 관리자 두 개)을 엽니다.
    inpath = Path("sample.csv")
    outpath = Path("out/transformed.csv")
    args = {"newline": "", "encoding": "utf-8-sig"}
    with inpath.open("r", **args) as infile, outpath.open("w", **args) as outfile:
        reader = csv.DictReader(infile)
        writer = csv.DictWriter(outfile, ["Firstname", "Lastname", "Username"])
    

    As you may already be aware, it is possible to pass a dictionary of keyword arguments to a Python function. Because both open() functions needed the same newline and encoding arguments, I built a dictionary with those then pass it to each open(), prefixing the necessary **. That way I don't repeat myself.


    위의 (완전하지 않은) 예는 줄 처리 논리로 작성할 수 있으며, 이렇게 하면 모든 줄을 읽고 변환하고 쓸 수 있다.
    전체 예를 살펴보겠습니다.
    import csv
    from pathlib import Path
    
    
    def transform():
        """Filters and transforms each row of input CSV, with output to a separate file."""
        inpath = Path("sample.csv")
        outpath = Path("out/transformed.csv")
        outpath.parent.mkdir(exist_ok=True)
        args = {"newline": "", "encoding": "utf-8-sig"}
        with inpath.open("r", **args) as infile, outpath.open("w", **args) as outfile:
            reader = csv.DictReader(infile)
            writer = csv.DictWriter(outfile, ["Firstname", "Lastname", "Username"])
    
            writer.writeheader()
    
            for row in reader:
                if row["Role"] == "Student":
                    new_row = {
                        "Firstname": row["First name"],
                        "Lastname": row["Last name"],
                        "Username": f"{row['Last name']}{row['First name']}".lower(),
                    }
                    writer.writerow(new_row)
    
    
    if __name__ == "__main__":
        transform()
    
    너도 download the code here을 선택할 수 있다.
    상기 코드를 simpletransform.py으로 저장하고 python simpletransform.py과 함께 실행하면 transformed.csv 디렉터리에 새로운 out/ 파일을 신속하게 만들 수 있습니다. 그 내용은 다음과 같습니다.
    성함
    의 성씨
    사용자 이름
    페니건
    룬돌프
    론도프 포니건
    이스턴
    덮다
    후드이스톤
    이 슬라이드에서는 다음과 같은 몇 가지 일반적인 변환 작업을 보여 줍니다.
  • 필드(열 머리글)의 이름을 기본 설정으로 바꿉니다(공백 없음!)
  • 우리는 하나의 값에 따라 선별했다. 우리는'학생'역할을 가진 줄만 바꾸고 썼다.
  • 사용자 이름 공식을 사용하여 값을 추가했습니다(성과 이름이 연결되어 있는 모든 소문자
  • )
    분명히 당신의 상상력은 데이터에 대한 더 복잡하고 유용한 전환을 고려하고 있습니다.가자.

    더욱 좋은 재사용 가능성과 명령행 처리
    만약 더 좋은 매개 변수화와 명령행 지원이 없다면, 나는 우리의 CSV transformer가 완전하지 않다고 생각한다.보통 나는 이런 도구가 반복적으로 유연하게 사용되기를 바란다. 만약 내가 그 중의 입력을 잊어버리면 의미 있는 피드백을 받을 수 있고, 수개월 동안의 고민 끝에 내가 다시 그것을 사용할 때 의미 있는 문서를 얻을 수 있기를 바란다.
    파이썬에는 argparse 이라는 명령줄 해상도가 포함되어 있습니다.다음 마지막 예제에서 사용할 것입니다.
    """Python CSV handling demo."""
    
    __version__ = "0.1.0"
    
    import argparse
    import csv
    import sys
    from pathlib import Path
    
    
    def transform(
        infilename, outfilename, inencoding="utf-8-sig", outencoding="utf-8-sig",
    ):
        """Filters and transforms each row, with output to a separate file."""
        inpath = Path(infilename)
        outpath = Path(outfilename)
        args = {"newline": ""}
        inargs = {"encoding": inencoding, **args}
        outargs = {"encoding": outencoding, **args}
        with inpath.open("r", **inargs) as infile, outpath.open("w", **outargs) as outfile:
            reader = csv.DictReader(infile)
            writer = csv.DictWriter(outfile, ["Firstname", "Lastname", "Username"])
    
            writer.writeheader()
    
            for row in reader:
                if row["Role"] == "Student":
                    new_row = {
                        "Firstname": row["First name"],
                        "Lastname": row["Last name"],
                        "Username": f"{row['Last name']}{row['First name']}".lower(),
                    }
                    writer.writerow(new_row)
    
    
    def run(args=None):
        """Execute as command line script."""
        if not args:
            args = sys.argv[1:]
        parser = argparse.ArgumentParser()
        parser.add_argument(
            "inputfile", help="read from this CSV file",
        )
        parser.add_argument(
            "outputfile", help="save to this CSV file",
        )
        parser.add_argument(
            "-e",
            "--encoding",
            default="utf-8-sig",
            help="character encoding of input and output files",
        )
        parser.add_argument(
            "-ie", "--inputencoding", help="character encoding of input file",
        )
        parser.add_argument(
            "-oe", "--outputencoding", help="character encoding to use for output file",
        )
        args = parser.parse_args(args)
    
        inputencoding = args.inputencoding or args.encoding
        outputencoding = args.outputencoding or args.encoding
    
        transform(args.inputfile, args.outputfile, inputencoding, outputencoding)
    
    
    if __name__ == "__main__":
        run()
    
    위 파일을 csvdemo.py으로 저장하고 python csvdemo.py -h과 함께 실행하면 명령줄 옵션을 볼 수 있습니다.
    다음은 샘플 파일을 다시 분석하여 결과를 Microsoft Excel 버전의 읽기 쉬운 형식으로 out/sample_transformed.csv에 기록합니다.
    python csvdemo.py -e utf-8-sig sample.csv out/sample_transformed.csv
    
    라틴어(서유럽)로 인코딩하려는 경우 UTF-8의 입력 인코딩을 유지하면서 다른 출력 인코딩을 시도할 수 있습니다.
    python csvdemo.py -ie utf-8-sig -oe cp1252 sample.csv out/sample_transformed_western.csv
    
    읽은 것을 환영합니다. 이 명령행 해석 도구를 더욱 탐색하십시오.
    필요에 따라 조정하고 Python CSV docs에 문의하십시오.
    CSV 처리를 위한 자체 제작 도구를 즐겨보세요!좋은 데이터.

    좋은 웹페이지 즐겨찾기