129

我要求 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 非常陌生,并想确保我了解所有内容。

4

18 回答 18

116

您可以使用csv模块类的实例来推断 CSV 文件的格式,并检测是否存在标题行以及仅在必要时跳过第一行Sniffer的内置函数: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:
于 2012-07-05T18:11:23.543 回答
84

要跳过第一行,只需调用:

next(inf)

Python 中的文件是行上的迭代器。

于 2012-07-05T18:15:26.130 回答
36

借用python cookbook
更简洁的模板代码可能如下所示:

import csv
with open('stocks.csv') as f:
    f_csv = csv.reader(f) 
    headers = next(f_csv) 
    for row in f_csv:
        # Process row ...
于 2018-03-31T11:02:29.030 回答
25

在一个类似的用例中,我不得不在带有我的实际列名的行之前跳过烦人的行。这个解决方案效果很好。先读取文件,然后将列表传递给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)))
于 2014-12-18T23:16:50.123 回答
19

您通常会使用next(incsv)which 将迭代器前进一行,因此您跳过标题。另一个(假设你想跳过 30 行)是:

from itertools import islice
for row in islice(incsv, 30, None):
    # process
于 2012-07-05T17:26:10.380 回答
8

使用 csv.DictReader 而不是 csv.Reader。如果省略 fieldnames 参数,则 csvfile 第一行中的值将用作字段名称。然后,您将能够使用 row["1"] 等访问字段值

于 2012-07-05T17:53:17.560 回答
4

Python 2.x

csvreader.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

Python 3.x

csvreader.__next__()

返回 reader 的可迭代对象的下一行作为列表(如果对象是从 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
于 2020-07-26T04:49:38.360 回答
3

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
于 2018-10-09T18:21:45.380 回答
2

新的“pandas”包可能比“csv”更相关。下面的代码将读取一个 CSV 文件,默认情况下将第一行解释为列标题并找到列之间的最小值。

import pandas as pd

data = pd.read_csv('all16.csv')
data.min()
于 2014-08-28T15:43:50.953 回答
2

因为这与我正在做的事情有关,所以我会在这里分享。

如果我们不确定是否有标头并且您也不想导入嗅探器和其他东西怎么办?

如果您的任务是基本的,例如打印或附加到列表或数组,您可以只使用 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)
于 2018-05-01T18:06:14.107 回答
1

好吧,我的迷你包装库也可以完成这项工作。

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

同时,如果您知道标题列索引一是什么,例如“列 1”,您可以这样做:

>>> min(data.column["Column 1"])
于 2014-12-01T10:18:06.853 回答
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)
于 2020-03-27T11:21:57.337 回答
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])  
于 2018-03-12T12:44:08.670 回答
1

这可能是一个非常古老的问题,但是对于 pandas,我们有一个非常简单的解决方案

import pandas as pd

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

使用 skiprows=1 我们可以跳过第一行,然后我们可以使用 data['column'].min() 找到最小值

于 2020-09-16T01:34:57.780 回答
0

只需添加[1:]

下面的例子:

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

在 iPython 中对我有用

于 2015-11-01T00:02:39.093 回答
0

Python 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]
于 2016-10-26T09:32:51.130 回答
0

我会用tail去掉不需要的第一行:

tail -n +2 $INFIL | whatever_script.py 
于 2015-09-13T10:26:15.487 回答
0

简单的解决方案是使用 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.
于 2021-12-21T11:40:04.287 回答