2012-12-10 42 views
0

我正在处理超过6MM行的股票代码数据。我想抓住符号的所有数据,执行我需要的处理,并输出结果。如何知道文件指针的位置,以便我可以识别文件中的起始位置

我已经编写了代码,告诉我每个代码的起始行(参见下面的代码)。我认为如果我知道一个新符号在什么位置开始(而不是行号)会更有效率,所以我可以使用seek(#)轻松跳转到股票代码的起始位置。我也很好奇如何扩展这个逻辑来读取股票代码的整个数据块(start_position到end_position)。

import csv 
data_line  = 0 # holds the file line number for the symbol 
ticker_start  = 0 
ticker_end   = 0 
cur_sec_ticker = "" 
ticker_dl = [] # array for holding the line number in the source file for the start of each ticker 
reader = csv.reader(open('C:\\temp\sample_data.csv', 'rb'), delimiter=',') 
for row in reader: 
    if cur_sec_ticker != row[1]: # only process a new ticker 
     ticker_fr = str(data_line) + ',' + row[1] # prep line for inserting into array 

     # desired line for inserting into array, ticker_end would be the last 
     # of the current ticker data block, which is the start of the next ticker 
     # block (ticker_start - 1) 
     #ticker_fr = str(ticker_start) + str(ticker_end) + str(data_line) + ',' + row[1] 

     print ticker_fr 
     ticker_dl.append(ticker_fr) 
     cur_sec_ticker = row[1] 
    data_line += 1 
print ticker_dl 

下面我放在如何将数据文件的小样本:

seq,Symbol,Date,Open,High,Low,Close,Volume,MA200Close,MA50Close,PrimaryLast,filter_$ 
1,A,1/1/2008,36.74,36.74,36.74,36.74,0, , ,1,1 
2,A,1/2/2008,36.67,36.8,36.12,36.3,1858900, , ,1,1 
3,A,1/3/2008,36.3,36.35,35.87,35.94,1980100, , ,1,1 
1003,AA,1/1/2008,36.55,36.55,36.55,36.55,0, , ,1,1 
1004,AA,1/2/2008,36.46,36.78,36,36.13,7801600, , ,1,1 
1005,AA,1/3/2008,36.18,36.67,35.74,36.19,7169000, , ,1,1 
2005,AAN,4/20/2009,20,20.7,18.2067,18.68,808700, , ,1,1 
2006,AAN,4/21/2009,18.7,19.06,18.6533,18.9933,530200, , ,1,1 
2007,AAN,4/22/2009,19.2867,19.6267,18.54,19.1333,801100, , ,1,1 
2668,AAP,1/1/2008,37.99,37.99,37.99,37.99,0, , ,1,1 
2669,AAP,1/2/2008,37.99,38.15,37.17,37.59,1789200, , ,1,1 
2670,AAP,1/3/2008,37.58,38.16,37.35,37.95,1584700, , ,1,1 
3670,AAR,1/1/2008,22.94,22.94,22.94,22.94,0, , ,1,1 
3671,AAR,1/2/2008,23.1,23.38,22.86,23.15,17100, , ,1,1 
3672,AAR,1/3/2008,23,23,22,22.16,45600, , ,1,1 
6886,ABB,1/1/2008,28.8,28.8,28.8,28.8,0, , ,1,1 
6887,ABB,1/2/2008,29,29.11,28.23,28.64,4697700, , ,1,1 
6888,ABB,1/3/2008,27.92,28.35,27.79,28.08,5240100, , ,1,1 
+0

seek()的反义词是tell() – SpacedMonkey

回答

1

在一般情况下,你可以得到与tell方法的文件对象的当前位置。但是,可能很难使用当前代码将文件读取到csv模块。在逐行读取时很难做到这一点,因为底层文件对象可能会以比单行更大的块读取(readlinereadlines方法会在后台执行一些缓存以将其隐藏)。

虽然我忽略了阅读特定字节的全部想法,但如果它对您的程序来说真的值得,那么您可能需要负责阅读您自己的文件,以便您可以确切地了解您的位置该文件在任何时候。 tell可能没有必要。

像这样的东西可能会奏效读取数据块,然后将其拆分成线和价值观,同时跟踪的多少字节迄今已阅读:

def generate_values(f): 
    buf = "" # a buffer of data read from the file 
    pos = 0 # the position of our buffer within the file 

    while True: # loop until we return at the end of the file 
     new_data = f.read(4096) # read up to 4k bytes at a time 

     if not new_data: # quit if we got nothing 
      if buf: 
       yield pos, buf.split(",") # handle any data after last newline 
      return 

     buf += new_data 
     line_start = 0 # index into buf 

     try: 
      while True: # loop until an exception is raised at end of buf 
       line_end = buf.index("\n", line_start) # find end of line 
       line = buf[line_start:line_end] # excludes the newline 

       if line: # skips blank lines 
        yield pos+line_start, line.split(",") # yield pos,data tuple 

       line_start = line_end+1 
     except ValueError: # raised by `index()` 
      pass 

     pos += line_end + 1 
     buf = buf[line_end + 1:] # keep left over data from end of the buffer 

这可能需要一些调整,如果你的文件有\n以外的行结束,但它不应该太难。

+0

谢谢,我明白你已采取逻辑的位置,并理解其原因。鉴于我的代码,如果我累积每行的长度,我是否可以做类似的事情?我仍然能够分析我所在的股票,并且至少可以获取每个股票的起始文件位置。 –

+0

@ Dr.EMG:理论上你可能能够重建一条线的长度,但实际上可能很难做到这一点,因为你无法控制线条阅读,价值分割或其他细节,并且几个字节可能会在这里或那里错位,而没有你注意的机会。如果你想坚持'csv'模块,我建议你避免处理文件的位置,并简单地使用它们读取的行。 – Blckknght

+0

由于csv解析,实现我的建议不起作用(正如你在书中所暗示的那样)。我可以合并这两个过程:使用readline()获取长度并累积它,然后使用csv分析器解析该行以识别我所处的行情。我可以放弃捕获结束,但也可以通过排队ticker_dl数组的当前和下一个索引来知道下一个符号开始时的结束位置。 –

相关问题