处理CSV数据时,如何忽略第一行数据?

时间:2012-07-05 17:20:17

标签: python 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非常陌生,并希望确保我理解所有内容。

17 个答案:

答案 0 :(得分:99)

您可以使用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:

答案 1 :(得分:54)

要跳过第一行,请致电:

next(inf)

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

答案 2 :(得分:20)

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

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

答案 3 :(得分:18)

在类似的用例中,我必须在使用实际列名称之前跳过烦人的行。这个解决方案效果很好。首先阅读文件,然后将列表传递给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)))

答案 4 :(得分:12)

借鉴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 ...

答案 5 :(得分:6)

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

答案 6 :(得分:2)

新的'pandas'包可能比'csv'更有意义。下面的代码将读取CSV文件,默认情况下将第一行解释为列标题,并找到跨列的最小值。

import pandas as pd

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

答案 7 :(得分:1)

好吧,我的mini wrapper library也能完成这项工作。

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

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

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

答案 8 :(得分: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

答案 9 :(得分:1)

我将csvreader转换为list,然后弹出第一个元素

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)

答案 10 :(得分: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])  

答案 11 :(得分:1)

documentation for the Python 3 CSV module提供了以下示例:

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

答案 12 :(得分:0)

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

import pandas as pd

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

with skiprows = 1,我们可以跳过第一行,然后使用data ['column']。min()

找到最小值

答案 13 :(得分:0)

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

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

如果你的任务是基本的,比如打印或附加到列表或数组,你可以使用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)

答案 14 :(得分: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]

答案 15 :(得分:0)

只需添加 [1:]

以下示例:

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

在iPython中适用于我

答案 16 :(得分:0)

我会使用 tail 来摆脱不必要的第一行:

tail -n +2 $INFIL | whatever_script.py