CSV 데이터를 처리 할 때 데이터의 첫 줄을 무시하는 방법은 무엇입니까?


113

Python에 CSV 데이터 열에서 최소 수를 인쇄하도록 요청하고 있지만 맨 위 행은 열 번호이며 Python이 맨 위 행을 고려하지 않기를 바랍니다. 파이썬이 첫 번째 줄을 무시하도록하려면 어떻게해야합니까?

이것은 지금까지의 코드입니다.

import csv

with open('all16.csv', 'rb') as inf:
    incsv = csv.reader(inf)
    column = 1                
    datatype = float          
    data = (datatype(column) for row in incsv)   
    least_value = min(data)

print least_value

코드 만 제공하는 것이 아니라 무엇을하는지 설명해 주시겠습니까? 저는 Python을 처음 접했고 모든 것을 이해하고 있는지 확인하고 싶습니다.


5
1.0파일의 각 줄에 대해 a 를 반환 하고 최소값을 취하는 생성기를 만들고 있다는 것을 알고 1.0있습니까?
Wooble 2012-07-05

@Wooble 기술적으로는 1.0. :)
Dougal

@Wooble 좋은 캐치-... datatype(row[column]... 나는 OP가 달성하려고 노력하고 있다고 생각하는 것입니다
Jon Clements

나는 누군가가 나를 위해 그 코드를 작성했고 그것을 잡지 못했다. 그래서 감사합니다 haha!

답변:


106

csv모듈 Sniffer클래스 의 인스턴스를 사용하여 CSV 파일의 형식을 추론하고 헤더 행이 내장 next()함수 와 함께 존재하는지 여부를 감지하여 필요한 경우에만 첫 번째 행을 건너 뛸 수 있습니다.

import csv

with open('all16.csv', 'r', newline='') as file:
    has_header = csv.Sniffer().has_header(file.read(1024))
    file.seek(0)  # Rewind.
    reader = csv.reader(file)
    if has_header:
        next(reader)  # Skip header row.
    column = 1
    datatype = float
    data = (datatype(row[column]) for row in reader)
    least_value = min(data)

print(least_value)

이후 datatypecolumn귀하의 예제에 하드 코딩되어, 그것을 처리하기 위해 약간 빠른 것 row같은를 :

    data = (float(row[1]) for row in reader)

참고 : 위 코드는 Python 3.x 용입니다. Python 2.x의 경우 다음 줄을 사용하여 표시된 파일 대신 파일을 엽니 다.

with open('all16.csv', 'rb') as file:

2
대신에 has_header(file.read(1024))쓰는 것이 합리적 has_header(file.readline())입니까? 나는 많이 볼 수 있지만, 나는 이해가 안 돼요 has_reader()... CSV 파일의 한 줄에서 헤더 거기에 있는지 여부를 감지 할 수
ANTO

1
@Anto : 내 대답의 코드는 문서의 "Sniffer 사용 예제"를 기반으로 하므로이를 수행하는 규정 된 방법이라고 가정합니다. 나는 항상 충분한 데이터가 이러한 결정을-하지만 만들기 위해 나는 이후 아무 생각이없는 것처럼 하나 개의 데이터 라인을 기준으로 그 일을하는 것이하지 않는 것 같습니다 동의 방법Sniffer 작품 설명되지 않습니다. FWIW 사용되는 것을 본 적이 없으며has_header(file.readline()) 대부분의 경우 작동하더라도 명시된 이유 때문에 접근 방식이 의심 스럽습니다.
martineau

귀하의 의견에 감사드립니다. 그럼에도 불구하고를 사용 file.read(1024) 하면 파이썬의 csv lib에서 오류가 발생 하는 것 같습니다 . 예를 들어 여기 를 참조하십시오 .
Anto

@Anto : 저는 그런 오류를 경험 한 적이 없습니다. 1024 바이트는 결국 메모리가 많지 않습니다. 문서를 읽고 따라 간 사람들의). 이러한 이유로 다른 문제가 귀하의 문제를 일으키고 있다고 강력히 의심합니다.
martineau

에서 readline()로 전환하자마자 똑같은 오류가 발생했습니다 read(1024). 지금까지 csv.dialect 문제를 해결하기 위해 readline으로 전환 한 사람 만 찾았습니다.
Anto

75

첫 번째 줄을 건너 뛰려면 다음을 호출하십시오.

next(inf)

Python의 파일은 행에 대한 반복자입니다.


22

유사한 사용 사례에서 실제 열 이름이있는 줄 앞에 성가신 줄을 건너 뛰어야했습니다. 이 솔루션은 잘 작동했습니다. 먼저 파일을 읽은 다음 목록을 csv.DictReader.

with open('all16.csv') as tmp:
    # Skip first line (if any)
    next(tmp, None)

    # {line_num: row}
    data = dict(enumerate(csv.DictReader(tmp)))

감사합니다 Veedrac. 여기서 배우게되어 기쁩니다. 인용 한 문제를 해결할 수있는 편집을 제안 해 주시겠습니까? 내 솔루션이 작업을 완료했지만 더 개선 될 수있는 것 같습니까?
Maarten

1
코드를 동일해야하는 (예상되지 않은) 것으로 대체하는 편집을 제공했습니다. 의미와 일치하지 않는 경우 언제든지 되돌릴 수 있습니다. 나는 아직도 당신이 data사전을 만드는 이유를 확신하지 못하며 ,이 대답은 실제로 받아 들여진 것 위에 아무것도 추가하지 않습니다.
Veedrac

감사합니다 Veedrac! 실제로 매우 효율적으로 보입니다. 받아 들인 답변이 저에게 효과가 없었기 때문에 답변을 게시했습니다 (지금 이유를 기억할 수 없습니다). data = dict ()를 정의한 다음 즉시 채우는 데 문제가 있습니까 (제안과 비교하여)?
Maarten

1
작성하고 채우는 것은 잘못data = dict()아니지만 비효율적이고 관용적이지 않습니다. 또한 dict 리터럴 ( {})을 사용해야합니다 enumerate.
Veedrac

1
FWIW, @Veedrac내가 알림을 받고 싶다면 내 게시물에 답장해야합니다 .하지만 Stack Overflow는 사용자 이름에서 추측 할 수있는 것 같습니다. ( @Maarten답변자에게 기본적으로 알림이 전송되므로 작성하지 않습니다 .)
Veedrac

21

에서 차용 파이썬 요리 책 ,
더 간결 템플릿 코드는 다음과 같습니다

import csv
with open('stocks.csv') as f:
    f_csv = csv.reader(f) 
    headers = next(f_csv) 
    for row in f_csv:
        # Process row ...

19

일반적으로 next(incsv)반복자를 한 행 앞당기는 것을 사용 하므로 헤더를 건너 뜁니다. 다른 하나 (30 행을 건너 뛰고 싶었다고 가정)는 다음과 같습니다.

from itertools import islice
for row in islice(incsv, 30, None):
    # process

6

csv.Reader 대신 csv.DictReader를 사용하십시오. fieldnames 매개 변수를 생략하면 csvfile의 첫 번째 행에있는 값이 필드 이름으로 사용됩니다. 그러면 row [ "1"] 등을 사용하여 필드 값에 액세스 할 수 있습니다.


2

새로운 'pandas'패키지는 'csv'보다 관련성이 더 높을 수 있습니다. 아래 코드는 기본적으로 첫 번째 줄을 열 헤더로 해석하고 열에서 최소값을 찾는 CSV 파일을 읽습니다.

import pandas as pd

data = pd.read_csv('all16.csv')
data.min()

당신은 한 줄에 너무 쓸 수 있습니다 :pd.read_csv('all16.csv').min()
핀 ARUP 닐슨에게

1

음, 내 미니 래퍼 라이브러리도 작업을 수행합니다.

>>> import pyexcel as pe
>>> data = pe.load('all16.csv', name_columns_by_row=0)
>>> min(data.column[1])

한편, 헤더 열 인덱스 1이 무엇인지 (예 : "Column 1") 알고있는 경우 대신 다음을 수행 할 수 있습니다.

>>> min(data.column["Column 1"])

1

나에게 가장 쉬운 방법은 범위를 사용하는 것입니다.

import csv

with open('files/filename.csv') as I:
    reader = csv.reader(I)
    fulllist = list(reader)

# Starting with data skipping header
for item in range(1, len(fulllist)): 
    # Print each row using "item" as the index value
    print (fulllist[item])  

1

이것은 제가하고있는 일과 관련이 있기 때문에 여기서 공유하겠습니다.

헤더가 있는지 확실하지 않고 스니퍼 및 기타 항목을 가져오고 싶지 않은 경우 어떻게해야합니까?

목록이나 배열에 인쇄하거나 추가하는 것과 같이 기본 작업 인 경우 if 문을 사용할 수 있습니다.

# Let's say there's 4 columns
with open('file.csv') as csvfile:
     csvreader = csv.reader(csvfile)
# read first line
     first_line = next(csvreader)
# My headers were just text. You can use any suitable conditional here
     if len(first_line) == 4:
          array.append(first_line)
# Now we'll just iterate over everything else as usual:
     for row in csvreader:
          array.append(row)

1

파이썬 3 CSV 모듈에 대한 문서는 이 예제를 제공합니다 :

with open('example.csv', newline='') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(1024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    # ... process CSV file contents here ...

Sniffer시도 할 CSV 파일에 대한 많은 것들을 자동으로 감지합니다. has_header()파일에 헤더 행이 있는지 확인하려면 해당 메서드 를 명시 적으로 호출해야합니다 . 그렇다면 CSV 행을 반복 할 때 첫 번째 행을 건너 뜁니다. 다음과 같이 할 수 있습니다.

if sniffer.has_header():
    for header_row in reader:
        break
for data_row in reader:
    # do something with the row

0

꼬리 를 사용 하여 원하지 않는 첫 번째 줄을 제거합니다.

tail -n +2 $INFIL | whatever_script.py 

0

그냥 [1 :] 추가

아래 예 :

data = pd.read_csv("/Users/xyz/Desktop/xyxData/xyz.csv", sep=',', header=None)**[1:]**

그것은 iPython에서 나를 위해 작동합니다.


0

파이썬 3.X

UTF8 BOM + HEADER 처리

csv모듈이 헤더를 쉽게 얻을 수 없다는 것은 매우 실망 스러웠습니다. UTF-8 BOM (파일의 첫 번째 문자)에도 버그가 있습니다. 이것은 csv모듈 만 사용하여 나를 위해 작동 합니다.

import csv

def read_csv(self, csv_path, delimiter):
    with open(csv_path, newline='', encoding='utf-8') as f:
        # https://bugs.python.org/issue7185
        # Remove UTF8 BOM.
        txt = f.read()[1:]

    # Remove header line.
    header = txt.splitlines()[:1]
    lines = txt.splitlines()[1:]

    # Convert to list.
    csv_rows = list(csv.reader(lines, delimiter=delimiter))

    for row in csv_rows:
        value = row[INDEX_HERE]

0

csvreader를 목록으로 변환 한 다음 첫 번째 요소를 팝합니다.

import csv        

with open(fileName, 'r') as csvfile:
        csvreader = csv.reader(csvfile)
        data = list(csvreader)               # Convert to list
        data.pop(0)                          # Removes the first row

        for row in data:
            print(row)

0

Python 2.x

csvreader.next()

리더의 반복 가능한 객체의 다음 행을 현재 방언에 따라 구문 분석 된 목록으로 반환합니다.

csv_data = csv.reader(open('sample.csv'))
csv_data.next() # skip first row
for row in csv_data:
    print(row) # should print second row

Python 3.x

csvreader.__next__()

리더의 반복 가능한 객체의 다음 행을 목록 (객체가 reader ()에서 반환 된 경우) 또는 dict (DictReader 인스턴스 인 경우)로 반환하고 현재 언어에 따라 구문 분석됩니다. 일반적으로 이것을 next (reader)라고 불러야합니다.

csv_data = csv.reader(open('sample.csv'))
csv_data.__next__() # skip first row
for row in csv_data:
    print(row) # should print second row
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.