Python 实例化一个包含x个零和其他零的矩阵

Python 实例化一个包含x个零和其他零的矩阵,python,arrays,for-loop,numpy,Python,Arrays,For Loop,Numpy,我希望能够快速实例化一个矩阵,其中一行中的前几个(可变数量)单元格为0,其余为1 假设我们想要一个3x4矩阵 我首先将矩阵实例化为所有矩阵: ones = np.ones([4,3]) 然后想象我们有一个数组,它显示有多少前导零: arr = np.array([2,1,3,0]) # first row has 2 zeroes, second row 1 zero, etc 所需结果: array([[0, 0, 1], [0, 1, 1], [0, 0, 0

我希望能够快速实例化一个矩阵,其中一行中的前几个(可变数量)单元格为0,其余为1

假设我们想要一个3x4矩阵

我首先将矩阵实例化为所有矩阵:

ones = np.ones([4,3])
然后想象我们有一个数组,它显示有多少前导零:

arr = np.array([2,1,3,0]) # first row has 2 zeroes, second row 1 zero, etc
所需结果:

array([[0, 0, 1],
       [0, 1, 1],
       [0, 0, 0],
       [1, 1, 1]])
In [43]: (np.arange(n) >= arr[:, np.newaxis]).astype(int)
Out[43]: 
array([[0, 1, 1, 1, 1],
       [0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1]])
显然,这也可以用相反的方式来完成,但是我会考虑1是默认值的方法,0将被替换。< /P>
避免某些愚蠢循环的最佳方法是什么?

这里有一种方法
n
是结果中的列数。行数由
len(arr)
确定


有两个部分来解释这是如何工作的。首先,如何创建带有
m
0和
n-m
1的行?为此,我们使用
np.arange
创建一个值为[0,1,…,n-1]的行:

In [35]: n
Out[35]: 5

In [36]: np.arange(n)
Out[36]: array([0, 1, 2, 3, 4])
接下来,将该数组与
m
进行比较:

In [37]: m = 2

In [38]: np.arange(n) >= m
Out[38]: array([False, False,  True,  True,  True], dtype=bool)
它给出一个布尔值数组;第一个
m
值为假,其余为真。通过将这些值转换为整数,我们得到一个0和1的数组:

In [39]: (np.arange(n) >= m).astype(int)
Out[39]: array([0, 0, 1, 1, 1])
为了在
m
值数组(您的
arr
)上执行此操作,我们使用;这是解释的第二个关键思想

注意
arr[:,np.newaxis]
给出的内容:

In [40]: arr
Out[40]: array([1, 2, 3, 0, 3])

In [41]: arr[:, np.newaxis]
Out[41]: 
array([[1],
       [2],
       [3],
       [0],
       [3]])
也就是说,
arr[:,np.newaxis]
arr
重塑为具有形状(5,1)的二维数组。(
arr.reformate(-1,1)
本可以替代。)现在,当我们将其与
np.arange(n)
(长度为
n
的一维阵列)进行比较时,广播开始起作用:

In [42]: np.arange(n) >= arr[:, np.newaxis]
Out[42]: 
array([[False,  True,  True,  True,  True],
       [False, False,  True,  True,  True],
       [False, False, False,  True,  True],
       [ True,  True,  True,  True,  True],
       [False, False, False,  True,  True]], dtype=bool)
正如@RogerFan在他的评论中指出的,这基本上是参数的外部产物,使用
=
操作

最后对type
int
进行强制转换可获得所需的结果:

array([[0, 0, 1],
       [0, 1, 1],
       [0, 0, 0],
       [1, 1, 1]])
In [43]: (np.arange(n) >= arr[:, np.newaxis]).astype(int)
Out[43]: 
array([[0, 1, 1, 1, 1],
       [0, 0, 1, 1, 1],
       [0, 0, 0, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 0, 1, 1]])

没有我想要的那么简洁(我正在试验),但这也可以完成以下工作:

>>> n = 3
>>> zeros = [2, 1, 3, 0]
>>> numpy.array([[0] * zeros[i] + [1]*(n - zeros[i]) for i in range(len(zeros))])
array([[0, 0, 1],
       [0, 1, 1],
       [0, 0, 0],
       [1, 1, 1]])
>>>

工作非常简单:将所需次数相乘连接起来,一个元素列出
[0]
[1]
,逐行创建数组。

为什么我没有想到?!;-)谢谢你的发帖。(+1)非常感谢!这个解释可能对未来的来访者有用(尽管你们现在可能正在做这个);(不需要方阵。结果的形状是
(len(arr),n)
,如答案中所述。我只是碰巧选择了
n=5
作为示例。@WarrenWeckesser Yea,我的错,我使用了错误的数组。更新了问题以明确排除此答案是有效的(我的错误),虽然可能对其他人仍然有用。(无否决票)@PascalvKooten是的,刚刚注意到。抱歉,有一个较短的方法,请给我一分钟:)另外,确保它也适用于非平方矩阵,请。@PascalvKooten完成-请试试这个。@PascalvKooten我怀疑您是否会注意到这样小的矩阵有任何显著的差异。我更喜欢先编写简单易读的代码,只有在发现并证明某个特定位置的性能问题后,才进行优化。