Python 根据1D计数器数组填充2D数组列

Python 根据1D计数器数组填充2D数组列,python,arrays,numpy,autofill,Python,Arrays,Numpy,Autofill,我正在寻找一种numpy解决方案,用不同的1D计数器数组(“下例中的cnt”)中定义的许多“1”值填充2D数组中的每一列(“下例中的a”) 我尝试了以下方法: import numpy as np cnt = np.array([1, 3, 2, 4]) # cnt array: how much elements per column are 1 a = np.zeros((5, 4)) # array that must be filled with 1s per

我正在寻找一种numpy解决方案,用不同的1D计数器数组(“下例中的cnt”)中定义的许多“1”值填充2D数组中的每一列(“下例中的a”)

我尝试了以下方法:

import numpy as np

cnt = np.array([1, 3, 2, 4])   # cnt array: how much elements per column are 1
a = np.zeros((5, 4))           # array that must be filled with 1s per column
for i in range(4):             # for each column
    a[:cnt[i], i] = 1          # all elements from top to cnt value are filled

print(a)
并给出所需的输出:

[[1. 1. 1. 1.] 
 [0. 1. 1. 1.]
 [0. 1. 0. 1.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]]
有没有一种更简单(更快)的方法,可以使用numpy例程来实现这一点,而不必对每列进行循环

a = np.full((5, 4), 1, cnt)
像上面这样的东西会很好,但不起作用


谢谢你抽出时间

您可以使用
np.where
和类似的广播:

>>> import numpy as np
>>> 
>>> cnt = np.array([1, 3, 2, 4])   # cnt array: how much elements per column are 1
>>> a = np.zeros((5, 4))           # array that must be filled with 1s per column
>>> 
>>> res = np.where(np.arange(a.shape[0])[:, None] < cnt, 1, a)
>>> res
array([[1., 1., 1., 1.],
       [0., 1., 1., 1.],
       [0., 1., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.]])
>>将numpy作为np导入
>>> 
>>>cnt=np.数组([1,3,2,4])#cnt数组:每列有多少个元素是1
>>>a=np.zeros((5,4))#数组,每列必须填充1
>>> 
>>>res=np.where(np.arange(a.shape[0])[:,None]>>res
数组([[1,1,1,1.],
[0., 1., 1., 1.],
[0., 1., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 0., 0.]])
或在适当的地方:

>>> a[np.arange(a.shape[0])[:, None] < cnt] = 1
>>> a
array([[1., 1., 1., 1.],
       [0., 1., 1., 1.],
       [0., 1., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.]])
>>a[np.arange(a.shape[0])[:,None]>>a
数组([[1,1,1,1.],
[0., 1., 1., 1.],
[0., 1., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 0., 0.]])

您可以使用
np.where
和类似的广播:

>>> import numpy as np
>>> 
>>> cnt = np.array([1, 3, 2, 4])   # cnt array: how much elements per column are 1
>>> a = np.zeros((5, 4))           # array that must be filled with 1s per column
>>> 
>>> res = np.where(np.arange(a.shape[0])[:, None] < cnt, 1, a)
>>> res
array([[1., 1., 1., 1.],
       [0., 1., 1., 1.],
       [0., 1., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.]])
>>将numpy作为np导入
>>> 
>>>cnt=np.数组([1,3,2,4])#cnt数组:每列有多少个元素是1
>>>a=np.zeros((5,4))#数组,每列必须填充1
>>> 
>>>res=np.where(np.arange(a.shape[0])[:,None]>>res
数组([[1,1,1,1.],
[0., 1., 1., 1.],
[0., 1., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 0., 0.]])
或在适当的地方:

>>> a[np.arange(a.shape[0])[:, None] < cnt] = 1
>>> a
array([[1., 1., 1., 1.],
       [0., 1., 1., 1.],
       [0., 1., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.]])
>>a[np.arange(a.shape[0])[:,None]>>a
数组([[1,1,1,1.],
[0., 1., 1., 1.],
[0., 1., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 0., 0.]])

感谢您的精彩回答:比我需要的功能更强大。“res”2D阵列仅根据“cnt”条件将单元更改为特定数字(在本例中为1),并在所有其他单元中保持“a”的原始值。这允许多个使用1D“cnt”阵列,动态调整2D“res”阵列。作为Python初学者,我很难将一维垂直数组“np.arange(a.shape[0])[:,None](本例中为5个元素)与一维水平数组“cnt”(本例中为4个元素)进行比较,以重建所需的二维“res”数组。谢谢@威尔默特:这种情况利用了广播。比较形状5x1和4的数组会产生以下结果:1)通过在左侧插入轴将操作数2提升为ndim 2->1x4 2)通过沿放大的轴重复,5x1和1x4都将提升为5x4(仅在概念上,没有实际复制数据)3)通过实际的元素比较,得到了一个布尔5x4数组。感谢您给出了奇妙的答案:甚至比我需要的更强大。“res”2D阵列仅根据“cnt”条件将单元更改为特定数字(在本例中为1),并在所有其他单元中保持“a”的原始值。这允许多个使用1D“cnt”阵列,动态调整2D“res”阵列。作为Python初学者,我很难将一维垂直数组“np.arange(a.shape[0])[:,None](本例中为5个元素)与一维水平数组“cnt”(本例中为4个元素)进行比较,以重建所需的二维“res”数组。谢谢@威尔默特:这种情况利用了广播。比较形状5x1和4的数组会产生以下结果:1)操作数2通过在左侧插入轴升级为ndim 2->1x4 2)5x1和1x4都通过沿放大的轴重复升级为5x4(仅在概念上,实际上没有复制数据)。3)完成实际的元素级比较,生成布尔5x4数组。