从需要.split(',')

时间:2016-12-01 18:25:00

标签: python arrays numpy

我试图将当前在for循环中的简单计算推送到numpy数组中。在这种情况下,它是对表格中字符串列表的计算:

strings = ['12,34', '56,78'...]

我需要:

  1. 用逗号分隔符分割字符串并产生两个整数,例如
    strings = [[12, 34], [56, 78]...]

  2. 将此嵌套列表仅过滤为符合某些任意条件的成员,例如子列表中的两个数字都在特定范围内。

  3. 我试图熟悉numpy库,但在处理初始列表时没有增加开销的情况下,我无法利用改进的计算速度。例如,我的直觉是在创建数组之前在Python中进行split()int()转换,但这最终比简单的for循环更昂贵。

    除此之外,我似乎无法将从初始列表创建的数组中执行此操作所需的各种numpy操作拼凑在一起。有没有一种理智的方法来做到这一点,或者对于像这样的事情只是使用过一次这样的事情会失去原因吗?

    注意:有一个较旧的答案here表明字符串操作应该在Python中完成,但它不能比较运行时,现在可能已经过时了。

    比较我的尝试:

    import random
    import datetime as dt
    import numpy as np
    
    raw_locs = [str(random.randint(1,100)) + ',' + str(random.randint(1,100)) 
                for x in xrange(100000)]
    
    if __name__ =='__main__':
    
        # Python approach
        start1 = dt.datetime.now()
        results = []
        for point in raw_locs:
            lon, lat = point.split(",")
            lat = int(lat)
            lon = int(lon)
            if 0 <= lon <= 50 and 50 <= lat <= 100:
                results.append(point)
        end1 = dt.datetime.now()
    
        # Python list comprehension prior to numpy array
        start2 = dt.datetime.now()
        converted_list = [map(int, item.split(',')) for item in raw_locs]
        end2 = dt.datetime.now()
    
        # List comprehension + numpy array creation
        start3 = dt.datetime.now()
        arr = np.array([map(int, item.split(',')) for item in raw_locs])
        end3 = dt.datetime.now()
    
        start4 = dt.datetime.now()   
        results2 = arr[((0 <= arr[:,0]) & (arr[:,0] <= 50) 
                        & (50 <= arr[:,1]) & (arr[:,1] <= 100))]
        end4 = dt.datetime.now()
    
        # Print results
        print "Pure python for whole solution took:                {}".format(end1 - start1)
        print "Just python list comprehension prior to array took: {}".format(end2 - start2)
        print "Comprehension + array creation took:                {}".format(end3 - start3)
        print "Numpy actual calculation took:                      {}".format(end4 - start4)
        print "Total numpy time:                                   {}".format(end4 - start3)
    

1 个答案:

答案 0 :(得分:4)

虽然我认为如果你使用类似timeit模块的东西,你的时间会更准确,但我认为最大的问题是你正在解析一个字符串列表。 Numpy的内置方法适用于任何一种方法。请注意,在你的numpy情况下,np.array()的输入是一个列表comp与其他内容。

这是我的建议:用逗号连接你的字符串列表以获得一个以逗号分隔的字符串,用numpy.fromstring解析它,然后将结果重新整形为两列:

arr = np.fromstring(','.join(raw_locs),sep=',').reshape(-1,2)

在我的笔记本电脑上添加上述内容的时间:

Pure python for whole solution took:                0:00:00.128965
Just python list comprehension prior to array took: 0:00:00.156092
Comprehension + array creation took:                0:00:00.186023
Join + fromstring took:                             0:00:00.035040
Numpy actual calculation took:                      0:00:00.001355
Total numpy time:                                   0:00:00.222454

请注意,默认情况下,上面将创建一个dtype numpy.float64数组,即使输入是整数。如果要保持数组的整数值,可以手动将dtype=np.int64关键字参数传递给fromstring