2016-09-26 27 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 /無論如何,如果獲取數據的地方也可以作爲生成器工作,那麼不會一次處理所有內容,如果是這樣,請儘可能將其更改爲生成器。在這兩種情況下,您都可以儘快處理您的數據。