0

所以我有一些 csv 数据,我需要的只是两个字段,然后我将使用收盘价进行一些计算,然后再有两个字段并以某种格式打印这四个字段。

我正在考虑使用这两个字段创建命名元组,然后在计算后添加其他两个字段的值。namedtuples 最好将其格式化为这种格式,另一种选择是否像字典或列表更好?

如果使用 namedtuples 是正确的方法,我如何只使用数据中的两个字段和两个可以添加值的字段来创建它们,我能够创建 namedtuples,但通过在数据上使用 splitlines() 和所有字段然后创建命名元组。

4

4 回答 4

1

我会使用一个字典列表。“命名元组”就像一个结构或类,因此,当你创建一个命名元组时,你需要知道属性是什么。此外,由于这个特殊结构没有 getter/setter 方法,命名元组是不可变的。这使得它对您的代码不灵活。当你想从命名元组中添加或删除一个属性时,你会怎么做?

在我看来,命名元组就像元组一样,具有使代码更具可读性的额外优点。因此,如果 tuple 不是您的任务的数据结构,那么使用命名 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"
....
于 2014-02-18T08:01:42.053 回答
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
于 2014-02-18T09:21:40.167 回答
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
于 2014-02-18T10:00:15.700 回答
0

我正在考虑使用数据创建带有“日期”和“关闭”字段的命名元组,然后在计算后添加“指标”和“信号”的值。

你不能。

如果你真的想要属性样式的访问,动态添加任意属性,方法是使用从object. 这正是类实例默认所做的。

namedtuple除此之外,还有一组固定的字段,作为每个类的一部分namedtuple,可以通过索引和名称访问这些字段。如果您想稍后添加新字段,您不希望它们被修复。所以,不要使用namedtuple.

但是,我认为您不需要属性访问或索引访问。你真正想要的是密钥访问。换句话说,一个dict.

如果您使用标准库中的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)
于 2014-02-18T08:49:30.973 回答