2016-09-26 3 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] 

Это, как правило, 1 около 5000 списков, и каждый раз в некоторое время 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), потому что вы должны быть уверены, что y является float number или вы получите сообщение об ошибке. Это гораздо труднее сделать, хотя почти все имеет строковое представление. Но я все же убедился, что я сделал сравнение в нижнем регистре с «nan» (с .lower()), так как «NaN» или «Nan» являются законными способами выражения «Не номер».

+1

Я тоже об этом думал, но вы могли бы еще больше проверить его с помощью быстрой проверки, чтобы увидеть, требуется ли вложенное list-comp: 'new_data = [[if, element == 'nan' else element для элемента в L], если 'nan' в L else L для L в данных] 'Если' 'nan" 'выталкивается из одного генератора (а не вводится вручную), вам, вероятно, не нужно проверять наличие изменений на нем , – Augusta

+1

Да, я не думал об этом, но это было бы быстрее, особенно если это происходит только «раз в несколько минут», как сказал 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 или если вы находитесь в питоне 2 imap

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

таким образом, вы получите работать с вашими данными, как только что поступают из базы данных/Quandl/whatever, предоставляется, если место, где вы получаете данные, также работает как генератор, то есть не обрабатывает все это сразу, и если это произойдет, заготовьте, чтобы поменять его на генератор. В любом случае с этим вы сможете как можно скорее работать с вашими данными.

Смежные вопросы