首页 文章

在不使用for循环的不等行长度的numpy数组中获取所需元素

提问于
浏览
0

我有下面的numpy数组:

array([['apple','banana','orange'],
   ['car','bike','train','ship','plane','scooter'],
   ['red','purple']], dtype=object)

数组中的各行长度不等,我想得到每行的最后一个元素 . 我可以通过运行for循环来获得这个,但我想可能有更直接的方法 . 我最接近的(错误的解决方案)是arr [:] [ - 1]它给了我最后一行的元素和arr [np.arange(len(arr)), - 1]它会抛出'IndexError'错误 .

我想要的输出是:

array([['orange','scooter','purple']], dtype=object)

我将不胜感激任何指导 . 谢谢 .

3 回答

  • 0

    使用循环理解: np.array([i[-1] for i in arr],dtype=object) 可能只是一种有效而快速的方法,特别是如果列表足够长的话 . 但是既然你要求一个非循环的解决方案,这里有一种方法可以使用np.concatenate获得一个扁平化的版本,然后使用适当的索引将其索引到每个列表的最终元素中 -

    np.concatenate(arr)[np.cumsum(map(len,arr))-1]
    

    有一个 map 运算符的使用,它几乎没有矢量化方法 .

    样品运行 -

    In [166]: arr
    Out[166]: 
    array([['apple', 'banana', 'orange'],
           ['car', 'bike', 'train', 'ship', 'plane', 'scooter'],
           ['red', 'purple']], dtype=object)
    
    In [167]: np.concatenate(arr)[np.cumsum(map(len,arr))-1]
    Out[167]: 
    array(['orange', 'scooter', 'purple'], 
          dtype='|S7')
    

    请注意,如果我们想要一个对象dtype数组,我们需要在索引之前转换为这样的dtype: np.concatenate(arr).astype(object) .

  • 1

    如果最快,请使用列表列表:

    import numpy as np
    import random
    
    items = ['apple','banana','orange', 'car','bike','train','ship','plane','scooter', 'red','purple']
    a = [random.sample(items, random.randint(2, 10)) for _ in range(1000)]
    b = np.array(a)
    
    %timeit [x[-1] for x in a] # 62.1 µs
    %timeit [x[-1] for x in b] # 75.9 µs
    f = np.frompyfunc(lambda x:x[-1], 1, 1)
    %timeit f(b)  # 165 µs
    
    import cytoolz
    %timeit list(cytoolz.pluck(-1, a)) # 42.7 µs
    %timeit list(cytoolz.pluck(-1, b)) # 75.8 µs
    
    import pandas as pd
    s = pd.Series(a)
    %timeit s.str[-1] # 965 µs
    

    即使您有DataFrame或Series对象,也可以先将其转换为列表:

    %timeit s.tolist() #45.6 µs
    
  • 1

    使用熊猫:

    In [87]: a
    Out[87]: array([['apple', 'banana', 'orange'], ['car', 'bike', 'train', 'ship', 'plane', 'scooter'], ['red', 'purple']], dtype=object)
    
    In [88]: df = pd.DataFrame(a)
    
    In [93]: df
    Out[93]:
                                              0
    0                   [apple, banana, orange]
    1  [car, bike, train, ship, plane, scooter]
    2                             [red, purple]
    
    In [94]: df[0].str[-1]
    Out[94]:
    0     orange
    1    scooter
    2     purple
    Name: 0, dtype: object
    

    或者作为NumPy数组:

    In [95]: df[0].str[-1].values
    Out[95]: array(['orange', 'scooter', 'purple'], dtype=object)
    

相关问题