我想csv.DictReader
从文件中推导出字段名。文档说 “如果省略了fieldnames参数,则csv文件的第一行中的值将用作字段名。",但在我的情况下,第一行包含标题,第二行包含名称。
我不能像Python 3.2 skip a line in csv.DictReader那样应用next(reader)
,因为字段名赋值是在初始化读取器时发生的(或者我做错了)。
csv文件(从Excel 2010导出,original source):
CanVec v1.1.0,,,,,,,,,^M
Entity,Attributes combination,"Specification Code
Point","Specification Code
Line","Specification Code
Area",Generic Code,Theme,"GML - Entity name
Shape - File name
Point","GML - Entity name
Shape - File name
Line","GML - Entity name
Shape - File name
Area"^M
Amusement park,Amusement park,,,2260012,2260009,LX,,,LX_2260009_2^M
Auto wrecker,Auto wrecker,,,2360012,2360009,IC,,,IC_2360009_2^M
字符串
我的代码:
f = open(entities_table,'rb')
try:
dialect = csv.Sniffer().sniff(f.read(1024))
f.seek(0)
reader = csv.DictReader(f, dialect=dialect)
print 'I think the field names are:\n%s\n' % (reader.fieldnames)
i = 0
for row in reader:
if i < 20:
print row
i = i + 1
finally:
f.close()
型
目前的成果:
I think the field names are:
['CanVec v1.1.0', '', '', '', '', '', '', '', '', '']
型
预期结果:
I think the field names are:
['Entity','Attributes combination','"Specification Code Point"',...snip]
型
我意识到,删除第一行并继续执行操作是一种权宜之计,但我正试图尽可能地接近原位阅读数据,并尽量减少手动干预。
3条答案
按热度按时间zkure5ic1#
在
f.seek(0)
之后插入:字符串
在初始化
DictReader
之前将文件指针前进到第二行。m1m5dgzv2#
我使用了itertools的islice。我的header位于一个大的preamble的最后一行。我已经传递了preamble并使用hederline作为字段名:
字符串
myss37ts3#
通用解决方案
这是一个更通用的解决方案,当它不确定标题将到达哪一行时。
这个解决方案还清理了标题-期望第一个“单词”(空格分隔)作为实际的列标题,尾部字符被视为注解(并被删除)。
无法完全在csv.DictReader中实现
在
csv.DictReader
中无法处理跳过行。首先,它没有“跳过行数”功能(如Pandas),而且,我们不知道它会有多少行。因此确定需要外部处理。文件内容需要读取和处理。清洁解决方案
欢迎提出改进建议,但此解决方案避免了导入不必要的库,并且不使用像closing a file within a context manager and re-opening it(!)这样的漏洞。
Python 3
字符串
请注意,这段代码不会产生问题中预期的结果,因为列标题在测试数据中包含空格,并且此解决方案具有清除列标题的特定功能。
如果列标题中允许空格,则删除该功能。
Slurping整个文件
这个解决方案会slurps整个文件,以便尽早丢弃文件句柄,因为它适用于较小的数据集。如果正在使用大数据集,则在
csvfile
上下文管理器中继续处理,不要将整个文件slurps到初始列表中。字段名处理
(field.strip().split() or [""])[0]
步骤用于获取干净的列标题。因为field.strip()
可以生成空字符串,那么field.strip().split()
也可以生成空列表,然后[][0]
将引发异常。这是
... or [""]
确保有一个长度为1或更大的列表,以避免提高IndexError
。为第一个项目编制索引是必要的,以便将列标题单元格中的第一个单词与其他注解分开(不允许使用换行符或逗号,请参见下文)。
漏洞
字段名处理必须手动完成,在
csv
之外。特别是,逗号分割的简单方法预计将从一行提供所有列标题。如果这两个规则中的一个或两个都被打破,则该代码将不会“实现”,并且处理将中断。