Python 使用numpy获取每列特定值的行索引

Python 使用numpy获取每列特定值的行索引,python,numpy,Python,Numpy,我有一个10000乘10000的矩阵,里面填充了1和0。我要做的是遍历每一列并找到包含值1的行 然后我想将它存储在一个新的矩阵中,该矩阵有两列:列1=列索引,列2=包含1的行索引数组。有些列根本没有1,在这种情况下,它将是一个空数组 尝试再次执行for循环,但计算效率低下 我试着用一个更小的矩阵 #sample matrix n = 4 mat = [[randint(0,1) for _ in range(n)] for _ in range(n)] arr = np.random.rand

我有一个10000乘10000的矩阵,里面填充了1和0。我要做的是遍历每一列并找到包含值1的行

然后我想将它存储在一个新的矩阵中,该矩阵有两列:列1=列索引,列2=包含1的行索引数组。有些列根本没有1,在这种情况下,它将是一个空数组

尝试再次执行for循环,但计算效率低下

我试着用一个更小的矩阵

#sample matrix
n = 4
mat = [[randint(0,1) for _ in range(n)] for _ in range(n)]

arr = np.random.randint(0, size=(4, 2))

for col in range(n):
    arr[n][1] = n
    arr[n][2] = np.where(col == 1)

但是对于一个10000乘10000的矩阵,这运行得相当慢。我想知道这是否正确,是否有更好的方法?

获取
a[I][j]==1的索引

您可以使用or有效地获取您正在查找的数据(0和1矩阵中1的位置),但是,您无法仅使用NumPy Ndarray以原始问题中指定的格式获取这些数据

您可以使用ndarray和标准Python列表的组合来实现指定格式的数据,但是,鉴于您使用的数据的大小,效率是至关重要的,因此我认为最好集中精力获取数据,而不是以不规则Python列表的ndarray格式获取数据

如果您提到的格式是一个硬要求,那么您总是可以在计算之后重新格式化结果(矩阵中的
1
),这样您的代码将受益于NumPy在繁重的计算过程中提供的优化,从而减少整个过程的执行时间

使用
np.argwhere()的示例

将numpy导入为np
a=np.random.randint(0,2,size=(4,4))
b=np.arg其中(a==1)
打印(f'a\n{a})
打印(f'b\n{b}')
输出

a
[[1 1 1 1]
 [0 0 0 0]
 [1 0 1 0]
 [1 1 1 1]]
b
[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 2]
 [3 0]
 [3 1]
 [3 2]
 [3 3]]
array([1])
如您所见,
np.argwhere(a==1)
返回一个ndarray,其值是包含
a
中位置索引的ndarray,其值(
x
)满足条件
x==1

我用
a=np.random.randint(0,2,size=(1000010000)
在我的笔记本电脑上试了几次上述方法(没什么特别的),每次大约3-5秒就完成了

获取行索引,其中所有值
!=1

如果您想存储
a
的所有行索引,其中不包含值
==1
,最简单的方法是(假设您使用的是上面的示例代码)可能是通过使用返回
b
中不存在的行索引数组,即包含
a
的所有行索引的数组与1d数组
b[0]
之间的设置差异,1d数组
b[0]
将是
a
中所有值的行索引,这些值
!=1

假设与上述示例相同的
a
b

c=np.setdiff1d(np.arange(a.shape[0]),b[:,0])
印刷品(c)
输出

a
[[1 1 1 1]
 [0 0 0 0]
 [1 0 1 0]
 [1 1 1 1]]
b
[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 2]
 [3 0]
 [3 1]
 [3 2]
 [3 3]]
array([1])
在上面的示例中,
c=[1]
as
1
a
中唯一不包含任何值的行索引

值得注意的是,如果将
a
定义为
np.random.randint(0,2,size=(1000010000)
,则
c
的概率不是零长度(即空)数组非常小。这是因为如果一行不包含值
==1
np。random
必须在一行中返回
0
10000次才能将
0
填充到一行中

为什么要使用多个NumPy数组?

我知道,使用
b
c
来存储与
a==1
a!=1
位置相关的结果似乎有些奇怪。为什么不按照您最初的问题中所述,使用不规则的
列表

简言之,答案是效率。通过使用NumPy数组,您将能够对数据进行矢量化计算,并在很大程度上避免昂贵的Python循环,其好处将大大放大,因为考虑到您正在处理的数据的大小,执行所花费的时间将反映出来


您可以始终以更人性化的不同格式存储数据,并根据需要将其映射回NumPy,但是与原始问题中的示例相比,上述示例可能会大大提高执行时的效率。

获取索引,其中
a[i][j]==1

您可以使用or有效地获取您正在查找的数据(0和1矩阵中1的位置),但是,您无法仅使用NumPy Ndarray以原始问题中指定的格式获取这些数据

您可以使用ndarray和标准Python列表的组合来实现指定格式的数据,但是,鉴于您使用的数据的大小,效率是至关重要的,因此我认为最好集中精力获取数据,而不是以不规则Python列表的ndarray格式获取数据

如果您提到的格式是一个硬要求,那么您总是可以在计算之后重新格式化结果(矩阵中的
1
),这样您的代码将受益于NumPy在繁重的计算过程中提供的优化,从而减少整个过程的执行时间

使用
np.argwhere()的示例

将numpy导入为np
a=np.random.randint(0,2,size=(4,4))
b=np.arg其中(a==1)
打印(f'a\n{a})
打印(f'b\n{b}')
输出

a
[[1 1 1 1]
 [0 0 0 0]
 [1 0 1 0]
 [1 1 1 1]]
b
[[0 0]
 [0 1]
 [0 2]
 [0 3]
 [2 0]
 [2 2]
 [3 0]
 [3 1]
 [3 2]
 [3 3]]
array([1])
如您所见,
np.argwhere(a==1)
返回一个ndarray,其值是包含
a
中位置索引的ndarray,其值(
x
)满足条件
x==1