2016-09-26 50 views
0

我目前正在收集来自quandl的数据并保存为列表的列表。该列表看起来是这样的(价格数据):最有效的方法来遍历列表

['2', 1L, datetime.date(1998, 1, 2), datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), '82.1900', '83.6200', '81.7500', '83.5000', '28.5183', 1286500.0] 

这是典型的约5000名单1,每一次在一段时间Quandl会吐回一些NaN值不喜欢被保存到数据库中。

['2', 1L, datetime.date(1998, 1, 2), datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), 'nan', 'nan', 'nan', 'nan', 'nan', 0] 

什么是迭代列表列表以将'nan'值更改为零的最有效方式?

我知道我可以做这样的事情,但它似乎效率很低。此操作将需要在11个不同的值执行* 5000个不同的日期* 500家公司:

def screen_data(data): 
    new_data = [] 
    for d in data: 
     new_list = [] 
     for x in d: 
      new_value = x 
      if math.isNan(x): 
       new_value = 0 
      new_list.append(new_value) 

     new_data.append(new_list) 
    return new_data 

我有兴趣,可以减少时间的任何解决方案。我知道DataFrames可能工作,但不知道它将如何解决NaN问题。

或者如果有办法将NaN值与浮点数一起包含在SQLServer5.6数据库中,那么更改数据库也是一个可行的选项。

+2

这可能在codereview.stackexchange.com上更好,但是您所描述的内容听起来像您必须检查每个列表中的每个值。 – AChampion

回答

2

不要创建一个新的列表 - 相反,修改旧列表就地:

import math 

def screenData(L): 
    for subl in L: 
     for i,n in enumerate(subl): 
      if math.isnan(n): subl[i] = 0 

我能想到的,只有这样,才能使这个速度,将与多处理

2

我没有计时,但是您是否尝试过使用与conditional expressions

例如:

import datetime 

data = [ 
    ['2', 1, datetime.date(1998, 1, 2), 
    datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), 
    datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), 
    '82.1900', '83.6200', '81.7500', '83.5000', 
    '28.5183', 1286500.0], 
    ['2', 1, datetime.date(1998, 1, 2), 
    datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), 
    datetime.datetime(2016, 9, 26, 1, 35, 3, 830563), 
    'nan', 'nan', 'nan', 'nan', 'nan', 0], 
] 

new_data = [[y if str(y).lower() != 'nan' else 0 for y in x] for x in data] 

print(new_data) 

我没有用math.isnan(y),因为你必须要确保yfloat number,否则你会得到一个错误。这样做要困难得多,而几乎所有东西都有字符串表示。但是我仍然确信我做了与'nan'(.lower())的小写比较,因为'NaN'或'Nan'是表达“不是数字”的合法方式。

+1

我也在想这个,但是你可以通过快速检查来看看它是否需要嵌套list-comp:'new_data = [[0 if element =='nan'else else for element in L]如果'nan'in L else L for data in data]'如果''nan''被推出单个生成器(而不是手动输入),那么您可能不需要检查它的变体。 – Augusta

+1

是的,我没有想过它,但它确实会更快,特别是如果它只发生在OP“每隔一段时间”就像OP说的那样。 – EvensF

0

这个怎么样

import math 

def clean_nan(data_list,value=0): 
    for i,x in enumerate(data_list): 
     if math.isnan(x): 
      data_list[i] = value 
    return data_list 

(返回值是可选的,因为修改被就地制造,但如果与map或类似使用它是必要的,假设当然是DATA_LIST非常列表或类似容器)

取决于你如何让你的数据,你如何与它会决定如何,如果你做这样的事情

for data in (my database/Quandl/whatever): 
    #do stuff with data 
使用它,例如工作

,你可以把它改成

for data in (my database/Quandl/whatever): 
    clean_nan(data) 
    #do stuff with data 

或使用map或者如果你是在Python 2 imap

for data in map(clean_nan,(my database/Quandl/whatever)): 
    #do stuff with data 

这样,你得到你的数据就从数据库到工作/ Quandl /无论如何,如果获取数据的地方也可以作为生成器工作,那么不会一次处理所有内容,如果是这样,请尽可能将其更改为生成器。在这两种情况下,您都可以尽快处理您的数据。