如何使用不同的默认值为每列初始化NumPy数组?

4
我正在尝试初始化一个大小为(x,y)的NumPy矩阵,其中y非常大。
矩阵的第一列是ID(整数),其余部分是三元组(int8),其中三元组的每个成员都应具有不同的默认值。
即假设默认值为[2,5,9],则我想初始化以下矩阵:
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
...

我能提供的最快初始化矩阵的方式是:
defaults = [2, 5, 9]
mat = numpy.zeros(shape=(x,y),
                  dtype=['i'] + ['int8'] * (y - 1))
# fill the triplets with default values
for i in range(1, y/3):
    j = i * 3
    mat[:, j]   = defaults[0]
    mat[:, j+1] = defaults[1]
    mat[:, j+2] = defaults[2]

如何快速初始化这样的矩阵?

谢谢!


你应该查看numpy.tile - xnx
3个回答

1
您可以使用np.tile函数并重塑值数组,例如:
>>> b=np.array([2,5,9])
>>> b=b.reshape(3,1)
>>> np.tile(b,3)
array([[2, 2, 2],
       [5, 5, 5],
       [9, 9, 9]])

然后您可以使用 np.dstack 旋转数组,然后使用 np.hstack 添加零列:
>>> np.hstack((np.zeros((3,1)),np.dstack(new)[0]))
array([[ 0.,  2.,  5.,  9.],
       [ 0.,  2.,  5.,  9.],
       [ 0.,  2.,  5.,  9.]])

或者你可以使用 tile 将非零部分重复:

>>> np.hstack((np.zeros((3,1)),np.tile(np.dstack(new)[0],4)))
array([[ 0.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.],
       [ 0.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.],
       [ 0.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.,  2.,  5.,  9.]])

编辑:

仅为澄清,简单的一行代码是这样的:

defaults = [2, 5, 9]
np.hstack((np.zeros((x,1)), np.tile(defaults, (x,y))))

0
一个更简单的解决方案是只使用 np.tile() 函数:
# Create a footprint array
a = np.array([2, 5, 9])

# Use the footprint array to create the required final array
res = np.tile(a, (4, 3))

>>>res
array([[2, 5, 9, 2, 5, 9, 2, 5, 9],
       [2, 5, 9, 2, 5, 9, 2, 5, 9],
       [2, 5, 9, 2, 5, 9, 2, 5, 9],
       [2, 5, 9, 2, 5, 9, 2, 5, 9]])

关于np.tile()的详细使用,请参见官方numpy页面


-1

我会这样做,

np.tile([0] + [2, 5, 9] * 4, (3, 1))

这里我使用了列表加法和乘法来创建第一行,然后使用np.tile将其复制到三行。 np.tile 在将列表垂直复制三次之前会自动将其转换为数组。如果您想要的话,您可以将此包装成一个类似于以下的函数:

def make_array(triple, n_triple, n_row):
    return np.tile([0] + list(triple) * n_triple, (n_row, 1))

在这里,我已经强制将triple转换为列表,但是如果您在调用此函数时仔细只传递一个列表给triple变量,那么您就不需要这样做。

祝好运


我觉得你有点混淆了——你在我的例子中写的n_y实际上是x。你还使用了列表乘法在y轴(列)上进行复制,我认为这比NumPy的方法慢。 - NStiner
我修改了我的解决方案,使其更具描述性。在我看来,你使用的 x, y 会让人感到困惑,因为 x, y 经常用于水平和垂直坐标(例如在绘图中)。就速度而言,当 n_triple 的值很大时,np.tile 确实更快,但大多数情况下这并不重要,我认为我的代码明显更简单、更易读。如果我正在编写一个快速且不太规范的脚本,我不必考虑 np.zerosnp.tilenp.hstack 的尺寸如何协同工作。 - farenorth
你关于 x, y 符号的说法是正确的,也许使用 m, n 会更好。关于列表乘法 - 的确更简单,但对于大的 y 值,它比 NumPy 实现要慢得多。无论如何,也许使用生成器表达式会更好,像这样 - (i for j in range(n_triple) for i in [2, 5, 9]) - NStiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接