【问题标题】:Numpy: Fix array with rows of different lengths by filling the empty elements with zerosNumpy:通过用零填充空元素来修复具有不同长度行的数组
【发布时间】:2015-11-09 08:27:42
【问题描述】:

我正在寻找的功能如下所示:

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

result = fix(data)
print result

[[ 1.  2.  3.  4.]
 [ 2.  3.  1.  0.]
 [ 5.  5.  5.  5.]
 [ 1.  1.  0.  0.]]

我正在使用的这些数据数组非常大,因此我非常感谢最有效的解决方案。

编辑:从磁盘读取数据作为列表的 python 列表。

【问题讨论】:

  • 只需将数据类型添加到数组函数调用中,np.array(...,dtype=np.float64)np.array(...,dtype=np.float64),或者使用 numpy 中的loadtxtsavetxt
  • @zeroth 我已经尝试过了,得到了 ValueError: setting an array element with a sequence。你能解释更多吗?
  • 它可能是一个大多数条目为零的稀疏矩阵吗?它可以作为密集矩阵放入内存中吗?
  • @musically_ut 不,它并不稀疏。结尾处通常只缺少 1-3 个元素。

标签: python arrays performance python-2.7 numpy


【解决方案1】:

这可能是一种方法 -

def numpy_fillna(data):
    # Get lengths of each row of data
    lens = np.array([len(i) for i in data])

    # Mask of valid places in each row
    mask = np.arange(lens.max()) < lens[:,None]

    # Setup output array and put elements from data into masked positions
    out = np.zeros(mask.shape, dtype=data.dtype)
    out[mask] = np.concatenate(data)
    return out

样本输入、输出-

In [222]: # Input object dtype array
     ...: data = np.array([[1, 2, 3, 4],
     ...:                  [2, 3, 1],
     ...:                  [5, 5, 5, 5, 8 ,9 ,5],
     ...:                  [1, 1]])

In [223]: numpy_fillna(data)
Out[223]: 
array([[1, 2, 3, 4, 0, 0, 0],
       [2, 3, 1, 0, 0, 0, 0],
       [5, 5, 5, 5, 8, 9, 5],
       [1, 1, 0, 0, 0, 0, 0]], dtype=object)

【讨论】:

  • 接受的答案几乎是正确的。我认为这是一个疏忽,但以下内容: # 每行中有效位置的掩码 mask = np.arange(lens.size) lens.size == max(lens)。如果不是,它不再工作......
  • 我认为lens.size 应该是lens.max() - 在你的回答中,这些等于制作一个方阵。但是尝试使用比行数更长的参差不齐的行,你会得到一个错误。
【解决方案2】:

您可以使用 pandas 代替 numpy:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame([[1, 2, 3, 4],
   ...:                    [2, 3, 1],
   ...:                    [5, 5, 5, 5],
   ...:                    [1, 1]], dtype=float)


In [3]: df.fillna(0.0).values
Out[3]: 
array([[ 1.,  2.,  3.,  4.],
       [ 2.,  3.,  1.,  0.],
       [ 5.,  5.,  5.,  5.],
       [ 1.,  1.,  0.,  0.]])

【讨论】:

  • 不过似乎不适用于更深的嵌套级别:(
【解决方案3】:

使用np.pad()

In [62]: arr
Out[62]: 
[array([0]),
 array([83, 74]),
 array([87, 61, 23]),
 array([71,  3, 81, 77]),
 array([20, 44, 20, 53, 60]),
 array([54, 36, 74, 35, 49, 54]),
 array([11, 36,  0, 98, 29, 87, 21]),
 array([ 1, 22, 62, 51, 45, 40, 36, 86]),
 array([ 7, 22, 83, 58, 43, 59, 45, 81, 92]),
 array([68, 78, 70, 67, 77, 64, 58, 88, 13, 56])]

In [63]: max_len = np.max([len(a) for a in arr])

In [64]: np.asarray([np.pad(a, (0, max_len - len(a)), 'constant', constant_values=0) for a in arr])
Out[64]: 
array([[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [83, 74,  0,  0,  0,  0,  0,  0,  0,  0],
       [87, 61, 23,  0,  0,  0,  0,  0,  0,  0],
       [71,  3, 81, 77,  0,  0,  0,  0,  0,  0],
       [20, 44, 20, 53, 60,  0,  0,  0,  0,  0],
       [54, 36, 74, 35, 49, 54,  0,  0,  0,  0],
       [11, 36,  0, 98, 29, 87, 21,  0,  0,  0],
       [ 1, 22, 62, 51, 45, 40, 36, 86,  0,  0],
       [ 7, 22, 83, 58, 43, 59, 45, 81, 92,  0],
       [68, 78, 70, 67, 77, 64, 58, 88, 13, 56]])

【讨论】:

    【解决方案4】:

    如果以某种矢量化的方式会很好,但我仍然是一个菜鸟,所以我现在能想到的就是它!

    import numpy as np,numba as nb
    a=np.array([[1, 2, 3, 4],
                     [2, 3, 1],
                     [5, 5, 5, 5,5],
                     [1, 1]])
    @nb.jit()
    def f(a):
        l=len(max(a,key=len))
        a0=np.empty(a.shape+(l,))
        for n,i in enumerate(a.flat):
            a0[n]=np.pad(i,(0,l-len(i)),mode='constant')
        a=a0
        return a
    
    print(f(a))
    

    【讨论】:

      【解决方案5】:
      data = np.array([[1, 2, 3, 4],
                       [2, 3, 1],
                       [5, 5, 5, 5],
                       [1, 1]])
      max_len=max([len(i) for i in data])
      np.array([ np.pad(data[i],
                 (0,max_len-len(data[i])),
                 'constant',
                  constant_values=0) for i in range(len(data))])
      

      计算各个数组的长度,然后将这些长度中的最大值存储在一个变量中。 之后,矩阵的所有单独行都在右侧用 0 填充以匹配最大长度。

      【讨论】:

        猜你喜欢
        • 2020-12-07
        • 2020-12-31
        • 2018-06-23
        • 2018-07-09
        • 2017-10-24
        • 1970-01-01
        • 2016-11-06
        • 1970-01-01
        相关资源
        最近更新 更多