我正在从彭博的开放符号学下载一个主数据表。csv有我不感兴趣的列。在
问题
有没有一种有效的/Pythonic方法可以从csv文件中找到的列的子集生成namedtuple实例?在
我尝试过的
我当前的流程(下面是Python 3.3代码)如下:
这闻起来很低效。在
from csv import reader
from collections import namedtuple
from datetime import date
from io import BytesIO
from urllib.request import urlopen
from urllib.error import HTTPError
from zipfile import ZipFile
def bsym_records(sector, security_type, file_date):
"""Yield BSYMRecord for given sector and security type."""
template = 'http://bdn-ak.bloomberg.com/precanned/{s}_{t}_{d}.txt.zip'
url = template.format(s=sector, t=security_type, d=file_date)
response = urlopen(url)
zipfile = ZipFile(BytesIO(response.read()))
for filename in zipfile.namelist():
with zipfile.open(filename) as f:
line = f.readline().decode('utf-8')
headers = line.strip().replace(' ', '_').split('|')
TempRecord = namedtuple('BSYMRecord', headers)
while True:
line = f.readline().decode('utf-8')
if line[0] == '#':
break
t = TempRecord._make(line.strip().split('|'))
yield reduce_bsym_record(t)
BSYMRecord = namedtuple('BSYMRecord', ['name',
'ticker',
'pricing_source',
'security_type',
'market_sector',
'BBGID',
'BBGID_composite',
'BSID',
'unique_id'])
def reduce_bsym_record(record):
"""Eliminate non-essential fields."""
return BSYMRecord._make((record.NAME,
record.ID_BB_SEC_NUM_DES,
record.FEED_SOURCE,
record.SECURITY_TYP,
record.MARKET_SECTOR_DES,
record.ID_BB_GLOBAL,
record.COMPOSITE_ID_BB_GLOBAL,
record.ID_BB_SEC_NUM_SRC,
record.ID_BB_UNIQUE))
您当前正在导入} 类为文件中的每一行创建一个字典,而不是一个列表。可以使用关键字参数构造
csv
模块,但没有使用它。如果正在使用它,那么可以使用^{namedtuple
,但它不会忽略伪参数。因此,您仍然需要手动筛选它们-但现在可以使用dict理解来完成此操作,而不是使用不同的namedtuple:诀窍是首先设置听写器。它需要一个生成字符串的类似文件的对象;
^{pr2}$ZipFile.open
提供一个文件类对象,该对象产生字节,并且不能接受编码。codecs模块在这里起到了拯救作用-您可以获得一个StreamReader,它可以透明地将utf8字节解码为字符串,如下所示:然后像这样使用它:
您可以使用
index
根据标题从每行中选择所需的值:这使您的当前保护不受字段顺序的更改和所需字段的单一定义的影响,但这意味着您不必为每一行创建
TempRecord
。在相关问题 更多 >
编程相关推荐