所以我有一些csv数据我需要从这个数据是两个字段,然后我将使用收盘价进行一些计算,并有两个以上的字段,并以某种格式打印这四个字段。
我正在考虑使用两个字段创建命名元组,然后在计算后添加其他两个字段的值。将namedtuples格式化为这种格式是最好的,另一种选择更像是dicts或list吗?
如果使用namedtuples是正确的方法我如何只使用数据中的两个字段和可以添加值的两个字段来创建它们,我就能够通过使用splitlines()创建namedtuples但包含所有字段数据,然后创建namedtuples。
答案 0 :(得分:1)
我会使用词典列表。 “named tuple”就像一个struct或class,因此,你需要创建一个命名元组时的属性。此外,由于此特殊结构没有getter / setter方法,因此名为tuple的不可变。这使得它对您的代码不灵活。当您想要从命名元组添加或删除属性时,您打算做什么?
在我看来,命名元组就像元组一样,具有使代码更具可读性的额外优点。因此,如果元组不是任务的数据结构,则使用命名没有意义元组。
// When you only extracts the "DATA" and "CLOSE" attributes, store each row as a dict
d1={"DATE":"2011-11-11", "CLOSE":570.00}
d2={"DATE":"2011-11-12", "CLOSE":580.00}
....
d = [d1, d2]
....
// When you want to add extra attributes to each row, just modify that row
d[0]["INDICATOR"]=560.00
d[1]["SIGNAL"]="SELL"
....
答案 1 :(得分:0)
我正在考虑用数据创建带有'date'和'close'字段的命名元组,然后在计算之后添加'indicator'和'signal'的值。
你不能。
如果你真的想要属性风格的访问,动态添加任意属性,那么这样做的方法是使用从object
派生的普通类。这正是类实例默认执行的操作。
namedtuple
添加的内容是一组固定的字段,作为每个namedtuple
类的一部分,其中字段可以通过索引和名称访问。如果您想稍后添加新字段,则不希望它们已修复。因此,请勿使用namedtuple
。
但是,我认为你不想要属性访问或索引访问;你真正想要的是键控访问。换句话说,dict
。
如果您在stdlib中使用csv
模块而不是尝试使用splitlines
并手动解析事物,这不仅简单,而且微不足道。例如:
with open('input.csv', 'rb') as f:
d = list(csv.DictReader(f))
for thing in d:
# whatever you want, including setting thing['Indicator'], etc.
with open('output.csv', 'wb') as f:
writer = csv.DictWriter(f, ('Date', 'Close', Indicator', 'Signal').
extrasaction='ignore', delimiter='\t')
writer.writerows(d)
答案 2 :(得分:0)
使用课程... KISS。
class ShareData:
def __init__(self, date, open_price, high_price, low_price, close_price,
volume, adj_close):
self.date = date
self.open_price = open_price
self.high_price = high_price
self.low_price = low_price
self.volume = volume
self.adj_close = adj_close
# your code to set these here.. or set them None and do it later
self.indicator = None
self.signal = None
return
答案 3 :(得分:0)
使用namedtuples
会很尴尬因为你想添加字段。字典在这方面非常灵活,下面的一个子类允许您访问其内容属性或使用通常的索引[]
表示法。我从这个SO answer得到了这个想法,但它已经存在了一段时间,形式略有不同。 csv
模块是读取(和写入)csv数据的最简单方法,所以我建议使用它而不是自己解析文件格式。
import csv
class AttrDict(dict):
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self
with open('input_data.csv', 'rb') as inf:
data = [AttrDict(d) for d in csv.DictReader(inf)]
for row in data:
# sample code that creates two new fields
row.Indicator = float(row.Close) * .80
row.Signal = "Sell" if row.Indicator > 950.00 else "Buy"
print 'DATE CLOSE INDICATOR SIGNAL'
for item in data:
print '{:12s}{:12s}{:<12.2f}{:12s}'.format(
item.Date, item.Close, item.Indicator, item.Signal)
输出:
DATE CLOSE INDICATOR SIGNAL
2014-02-12 1186.69 949.35 Buy
2014-02-11 1190.18 952.14 Sell
2014-02-10 1172.93 938.34 Buy
2014-02-07 1177.44 941.95 Buy
2014-02-06 1159.96 927.97 Buy
2014-02-05 1143.20 914.56 Buy
2014-02-04 1138.16 910.53 Buy
2014-02-03 1133.43 906.74 Buy