【问题标题】:Convert and pad a list to numpy array将列表转换并填充为 numpy 数组
【发布时间】:2015-03-09 12:21:13
【问题描述】:

我有一个任意深度嵌套的列表,其中包含不同长度的元素

my_list = [[[1,2],[4]],[[4,4,3]],[[1,2,1],[4,3,4,5],[4,1]]]

我想通过用 NaN 填充每个轴来将其转换为有效的数字(不是对象)numpy 数组。所以结果应该是这样的

padded_list = np.array([[[  1,   2, nan, nan],
                         [  4, nan, nan, nan],
                         [nan, nan, nan, nan]],
                        [[  4,   4,   3, nan],
                         [nan, nan, nan, nan],
                         [nan, nan, nan, nan]],
                        [[   1,  2,   1, nan],
                         [   4,  3,   4,   5],
                         [   4,  1, nan, nan]]])

我该怎么做?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    这适用于您的示例,不确定它能否正确处理所有极端情况:

    from itertools import izip_longest
    
    def find_shape(seq):
        try:
            len_ = len(seq)
        except TypeError:
            return ()
        shapes = [find_shape(subseq) for subseq in seq]
        return (len_,) + tuple(max(sizes) for sizes in izip_longest(*shapes,
                                                                    fillvalue=1))
    
    def fill_array(arr, seq):
        if arr.ndim == 1:
            try:
                len_ = len(seq)
            except TypeError:
                len_ = 0
            arr[:len_] = seq
            arr[len_:] = np.nan
        else:
            for subarr, subseq in izip_longest(arr, seq, fillvalue=()):
                fill_array(subarr, subseq)
    

    现在:

    >>> arr = np.empty(find_shape(my_list))
    >>> fill_array(arr, my_list)
    >>> arr
    array([[[  1.,   2.,  nan,  nan],
            [  4.,  nan,  nan,  nan],
            [ nan,  nan,  nan,  nan]],
    
           [[  4.,   4.,   3.,  nan],
            [ nan,  nan,  nan,  nan],
            [ nan,  nan,  nan,  nan]],
    
           [[  1.,   2.,   1.,  nan],
            [  4.,   3.,   4.,   5.],
            [  4.,   1.,  nan,  nan]]])
    

    我认为这大致就是 numpy 的形状发现例程所做的。由于无论如何都涉及到大量 Python 函数调用,因此它可能不会与 C 实现相比那么糟糕。

    【讨论】:

      【解决方案2】:

      首先,计算列和行的长度:

      len1 = max((len(el) for el in my_list))
      len2 = max(len(el) for el in list(chain(*my_list)))
      

      其次,追加缺失的nans:

      for el1 in my_list:
          el1.extend([[]]*(len1-len(el1)))
          for el2 in el1:
              el2.extend([numpy.nan] * (len2-len(el2)))
      

      【讨论】:

      • 这很好,但应该适用于任意深度嵌套的列表,例如 numpy.array
      猜你喜欢
      • 2016-12-01
      • 2017-03-08
      • 2019-08-30
      • 2015-01-07
      • 2021-06-09
      • 2015-12-05
      • 1970-01-01
      相关资源
      最近更新 更多