处理CSV数据时如何忽略第一行数据?
- 2024-12-26 08:43:00
- admin 原创
- 139
问题描述:
我要求 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 还很陌生,想确保我理解了一切。
解决方案 1:
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:
解决方案 2:
要跳过第一行,只需调用:
next(inf)
Python 中的文件是行上的迭代器。
解决方案 3:
借用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 ...
解决方案 4:
在类似的用例中,我不得不跳过包含实际列名的行之前的烦人的行。这个解决方案效果很好。首先读取文件,然后将列表传递给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)))
解决方案 5:
您通常会使用next(incsv)
which 将迭代器前进一行,因此您会跳过标题。另一个(假设您想跳过 30 行)将是:
from itertools import islice
for row in islice(incsv, 30, None):
# process
解决方案 6:
使用 csv.DictReader 而不是 csv.Reader。如果省略 fieldnames 参数,则 csvfile 第一行中的值将用作字段名称。然后,您将能够使用 row["1"] 等访问字段值
解决方案 7:
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 的可迭代对象的下一行作为列表返回(如果该对象是从 reader() 返回的)或字典返回(如果它是 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
解决方案 8:
这可能是一个非常老的问题,但有了熊猫,我们就有了一个非常简单的解决方案
import pandas as pd
data=pd.read_csv('all16.csv',skiprows=1)
data['column'].min()
使用 skiprows=1 我们可以跳过第一行,然后我们可以使用 data['column'].min() 找到最小值
解决方案 9:
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
解决方案 10:
新的“pandas”包可能比“csv”更相关。下面的代码将读取一个 CSV 文件,默认情况下将第一行解释为列标题并查找跨列的最小值。
import pandas as pd
data = pd.read_csv('all16.csv')
data.min()
解决方案 11:
因为这和我正在做的事情有关,所以我会在这里分享。
如果我们不确定是否有标题并且您也不想导入嗅探器和其他东西怎么办?
如果你的任务很基本,例如打印或附加到列表或数组,那么你可以使用 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)
解决方案 12:
嗯,我的迷你包装库也可以完成这项工作。
>>> import pyexcel as pe
>>> data = pe.load('all16.csv', name_columns_by_row=0)
>>> min(data.column[1])
同时,如果您知道标题列索引一是什么,例如“列 1”,您可以这样做:
>>> min(data.column["Column 1"])
解决方案 13:
对我来说,最简单的方法是使用范围。
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])
解决方案 14:
我会将 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)
解决方案 15:
我将使用tail去掉不需要的第一行:
tail -n +2 $INFIL | whatever_script.py
解决方案 16:
只需添加[1:]
例如:
data = pd.read_csv("/Users/xyz/Desktop/xyxData/xyz.csv", sep=',', header=None)**[1:]**
在 iPython 中对我有用
解决方案 17:
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]
解决方案 18:
简单的解决方案是使用 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.
解决方案 19:
生成器可用于应用定制的跳过逻辑。
例如,考虑一个包含多行一般信息的 CSV 文件:
Client name: George P. Burdell
Client number: 1234567
Client preferred languages: English, Spanish
Date,Description,Amount
2024-09-10,Deposit,$25.00
...
生成器可以搜索标题行,而不是跳过特定数量的行:
def open_file_and_skip_to(path, search_term):
found = False
with open(path) as f:
for line in f:
if search_term in line:
found = True
if found:
yield line
reader = csv.DictReader(open_file_and_skip_to(path, "Date,Description"))
for row in reader:
print(row)
具体来说,要跳过 N 行,请使用:
def open_file_and_skip_lines(path, num_lines=1):
with open(path) as f:
for line in f:
if num_lines > 0:
num_lines -= 1
continue
yield line