Как обрабатывать данные 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
Возвращает следующую строку повторяемого объекта читателя в виде списка, проанализированного в соответствии с текущим диалектом.
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
Возвращает следующую строку итерируемого объекта читателя как список (если объект был возвращен из 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