在具有numpy的矩阵中查找最大的行(具有最大长度的行)

时间:2019-02-20 19:26:22

标签: python numpy

我有一个包含行和列的大型数组。有些行比其他行大。我需要获取最大长度的行,即具有最大长度的行。我为此编写了一个简单的函数,但我希望它尽可能地受欢迎,例如numpy fast。当前,它看起来像这样:

示例数组:

values = [
    [1,2,3],
    [4,5,6,7,8,9],
    [10,11,12,13]
]

def values_max_width(values):
    max_width = 1
    for row in values:
        if len(row) > max_width:
            max_width = len(row)
    return max_width

有什么办法可以用numpy做到这一点吗?

2 个答案:

答案 0 :(得分:1)

不确定如何使其更快。我尝试在每个项目的长度上使用np.max,但这会花费更长的时间:

itemView = (ViewGroup) inflater.inflate(R.layout.list_item_crime, parent, false);
  

values_max_width花费了0.00598s

     

value_max_width_len花费了0.00994s

*编辑*

正如@Mstaino所建议的,使用map确实可以使此代码更快:

import numpy as np
import time

values = []
for k in range(100000):
    values.append(list(np.random.randint(100, size=np.random.randint(1000))))


def timeit(func):
    def wrapper(*args, **kwargs):
        now = time.time()
        retval = func(*args, **kwargs)
        print('{} took {:.5f}s'.format(func.__name__, time.time() - now))
        return retval
    return wrapper

@timeit
def values_max_width(values):
    max_width = 1
    for row in values:
        if len(row) > max_width:
            max_width = len(row)
    return max_width


@timeit
def value_max_width_len(values):
    return np.max([len(l) for l in values])


values_max_width(values)
value_max_width_len(values)
  

values_max_width花费了0.00598s

     

value_max_width_len花费了0.00499s

答案 1 :(得分:1)

In [261]: values = [ 
     ...:     [1,2,3], 
     ...:     [4,5,6,7,8,9], 
     ...:     [10,11,12,13] 
     ...: ] 
     ...:                                                                       
In [262]:                                                                       
In [262]: values                                                                
Out[262]: [[1, 2, 3], [4, 5, 6, 7, 8, 9], [10, 11, 12, 13]]
In [263]: def values_max_width(values): 
     ...:     max_width = 1 
     ...:     for row in values: 
     ...:         if len(row) > max_width: 
     ...:             max_width = len(row) 
     ...:     return max_width 
     ...:                                                                       
In [264]: values_max_width(values)                                              
Out[264]: 6
In [265]: [len(v) for v in values]                                              
Out[265]: [3, 6, 4]
In [266]: max([len(v) for v in values])                                         
Out[266]: 6
In [267]: np.max([len(v) for v in values])                                      
Out[267]: 6

您的循环和列表理解的速度相似,np.max慢得多-它必须首先将列表转换为数组。

In [268]: timeit max([len(v) for v in values])                                  
656 ns ± 16.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [269]: timeit np.max([len(v) for v in values])                               
13.9 µs ± 181 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [271]: timeit values_max_width(values)                                       
555 ns ± 13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如果您是从列表开始的,那么最好彻底测试列表的实现。 numpy在处理已编译的数组内容时速度很快,但是从列表创建数组很耗时。

直接从values制作数组并没有太大帮助。对象dtype数组中的结果:

In [272]: arr = np.array(values)                                                
In [273]: arr                                                                   
Out[273]: 
array([list([1, 2, 3]), list([4, 5, 6, 7, 8, 9]), list([10, 11, 12, 13])],
      dtype=object)

在这样的数组上的数学运算是命中注定的,总是比纯数值数组上的数学运算慢。我们可以在这样的数组上进行迭代,但是迭代的速度比在列表上慢。

In [275]: values_max_width(arr)                                                 
Out[275]: 6
In [276]: timeit values_max_width(arr)                                          
1.3 µs ± 8.27 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)