Как обрабатывать данные CSV, как игнорировать первую строку данных?

Я прошу Python напечатать минимальное число из столбца данных CSV, но верхняя строка - это номер столбца, и я не хочу, чтобы Python учитывал верхнюю строку. Как я могу убедиться, что 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 и хотел бы убедиться, что я все понимаю.

18 ответов

Решение

Вы могли бы использовать экземпляр 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)

поскольку datatype а также column жестко закодированы в вашем примере, было бы немного быстрее обрабатывать row как это:

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

Примечание: приведенный выше код предназначен для Python 3.x. Для Python 2.x используйте следующую строку, чтобы открыть файл вместо того, что показано:

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

Чтобы пропустить первую строку, просто позвоните:

next(inf)

Файлы в Python являются итераторами над строками.

Заимствовано из кулинарной книги питона,
Более краткий код шаблона может выглядеть так:

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

В аналогичном случае использования мне пришлось пропустить надоедливые строки перед строкой с моими фактическими именами столбцов. Это решение работало хорошо. Сначала прочитайте файл, а затем передайте список 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)))

Вы бы обычно использовали next(incsv) который продвигает итератор на одну строку, поэтому вы пропускаете заголовок. Другой (скажем, вы хотите пропустить 30 строк) будет:

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

Используйте csv.DictReader вместо csv.Reader. Если параметр fieldnames опущен, значения в первой строке csvfile будут использоваться в качестве имен полей. После этого вы сможете получить доступ к значениям поля, используя строку ["1"] и т. д.

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), проанализированный в соответствии с текущим диалектом. Обычно вы должны называть это следующим (читатель).

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

Это может быть очень старый вопрос, но с пандами у нас есть очень простое решение

import pandas as pd

data=pd.read_csv('all16.csv',skiprows=1)
data['column'].min()

с skiprows=1 мы можем пропустить первую строку, тогда мы сможем найти наименьшее значение, используя data['column'].min()

Документация для модуля Python 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

Новый пакет 'pandas' может быть более актуальным, чем 'csv'. Код ниже будет читать файл CSV, по умолчанию интерпретируя первую строку как заголовок столбца и находя минимум по столбцам.

import pandas as pd

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

Поскольку это связано с чем-то, что я делал, я поделюсь здесь.

Что если мы не уверены, есть ли заголовок, и вам также не хочется импортировать сниффер и другие вещи?

Если ваша задача базовая, такая как печать или добавление в список или массив, вы можете просто использовать оператор 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)

Для меня самый простой способ - использовать дальность.

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])  

Ну, моя мини-библиотека-обертка тоже справилась бы с этой задачей.

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

Между тем, если вы знаете, какой индекс столбца заголовка один, например, "Столбец 1", вы можете сделать это вместо этого:

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

Я бы преобразовал 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)

Python 3.X

Ручки UTF8 BOM + HEADER

Было довольно обидно, что csv модуль не может легко получить заголовок, есть также ошибка с спецификацией UTF-8 (первый символ в файле). Это работает для меня, используя только 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]

Простое решение - использовать csv.DictReader()

      import csv

def read_csv(file): with open(file, 'r') as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row["column_name"])  # Replace the name of column header.

Просто добавьте [1:]

пример ниже:

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

это работает для меня в iPython

Я бы использовал tail, чтобы избавиться от нежелательной первой строки:

tail -n +2 $INFIL | whatever_script.py 
Другие вопросы по тегам