迭代列表列表的最有效方法

时间:2016-09-26 02:01:37

标签: python performance list mysql-python nan

我正在从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个列表中的一个,并且每隔一段时间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问题。

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

3 个答案:

答案 0 :(得分:2)

不要创建新列表 - 而是编辑旧列表:

import math

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

我能想到的唯一方法就是使用多处理

来加快速度

答案 1 :(得分:2)

我还没有计时,但您是否尝试将nested list comprehensionconditional 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,否则您将收到错误消息。这几乎比较一切都有字符串表示要困难得多。但我仍然确保我将'小写'与.lower()进行小写比较,因为'NaN'或'Nan'是表达“非数字”的合法方式。

答案 2 :(得分: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 /等到达你就可以使用你的数据,如果你获得数据的地方也可以作为生成器使用,那就不会处理整个数据事情一下子,如果确实如此,如果可能的话,采购将其改为发电机。无论是哪种情况,您都可以尽快处理您的数据。