【问题标题】:Parse csv to dict将 csv 解析为 dict
【发布时间】:2013-09-19 03:09:32
【问题描述】:

我正在尝试将来自网络的 csv 财务数据解析为我可以按键导航的字典。
我使用 csv.DictReader 失败。
我有:

import csv
import urllib2
req = urllib2.Request('http://financials.morningstar.com/ajax/ReportProcess4CSV.html?&t=XNAS:BRCM&region=usa&culture=en-US&cur=USD&reportType=is&period=12&dataType=A&order=desc&columnYear=5&rounding=3&view=raw&r=886300&denominatorView=raw&number=3')
response = urllib2.urlopen(req)
response.next() 
csvio = (csv.DictReader(response))
print csvio.fieldnames 
print len(csvio.fieldnames)

已编辑以反映以下答案的变化。

这几乎可以让我到达那里,但我需要在将其提供给 DictReader 之前剥离领先的“财政年度...共享数据”。如何最好地做到这一点?我已经研究过使用 str.lstrip() 转换为字符串并剥离前导字符,因为文档说 here 没有运气。

【问题讨论】:

  • 顺便说一下,如果您要对表格数据进行大量工作,我建议您查看pandas。否则,您可能会花费大量时间重新设计其功能。

标签: python parsing csv financial


【解决方案1】:

要使用 DictReader,您需要指定字段名称,或者字段名称需要是 csv 数据的第一行(即标题行)。

在您的代码检索到的 csv 文件中,字段名称位于 第二 行数据中,而不是第一行。我所做的是在将 csv 文件传递​​给 DictReader 构造函数之前丢弃第一行数据。

针对您更新的问题: 从标题行中删除前导文本可能是不可取的,因为这充当了第一列数据的字段名称。最好丢弃前 2 行数据,然后将所需的字段名称直接提供给 DictReader。我更新了下面的示例以反映这一点。

import csv
import urllib2

req = urllib2.Request('http://financials.morningstar.com/ajax/ReportProcess4CSV.html?&t=XNAS:BRCM&region=usa&culture=en-US&cur=USD&reportType=is&period=12&dataType=A&order=desc&columnYear=5&rounding=3&view=raw&r=886300&denominatorView=raw&number=3')
response = urllib2.urlopen(req)

response.readline() # This reads (and discards) the first row of data which is not needed.
response.readline() # skip the 

myFieldnames = ["firstColName", "TTM", "2012", "2011", "2010", "2009", "2008"]
csvio = csv.DictReader(response, fieldnames=myFieldnames)

print csvio.fieldnames 
for row in csvio:
    print row

【讨论】:

  • 您的回复将我引向可迭代的 .next 方法。我现在有:'req = urllib2.Request('financials.morningstar.com/ajax/…) response = urllib2.urlopen(req) response.next() csvio = (csv.DictReader(response)) print csvio.fieldnames print len(csvio.fieldnames) '。这几乎可以让我到达那里,但我需要去掉领先的“财政年度......共享数据”。在将其提供给 DictReader 之前。如何最好地做到这一点?
  • 我认为去掉前导文本不是一个好主意,因为它充当了第一列数据的字段名称。一种解决方案是跳过前 2 行数据,然后将所需的字段名称直接提供给 DictReader。例如:csvio = csv.DictReader(response, fieldnames=["firstColName", "2012", "2011", "2010", "2009", "2008"])
  • 抱歉,错过了列名。应该是csvio = csv.DictReader(response, fieldnames=["firstColName", "TTM", "2012", "2011", "2010", "2009", "2008"])。无论如何,我已经更新了我的答案以反映这一点。
  • 这让我克服了困难。你怎么知道前导文本是第一列的字段名称(或者当它是一个 urllib2.urlopen() 对象时根本就是结构)?试着去理解,这样我将来可以问更聪明的问题(或者在不得不问之前解决)。谢谢。
  • @dman 我下载了 csv 文件并在文本编辑器中查看了它。我看到第一行根本不包含字段名称,第二行包含字段名称,但第一行并没有真正的意义。标题行应为随后数据行中的每个字段包含一个描述性字段名称。在现实世界中,我们不能总是依赖像这样正确格式化的源数据,这就是为什么最好检查数据并确定您可能必须执行的任何解决方法。
猜你喜欢
  • 2018-10-01
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2015-06-20
相关资源
最近更新 更多