Python 使用numpy获取每列特定值的行索引
我有一个10000乘10000的矩阵,里面填充了1和0。我要做的是遍历每一列并找到包含值1的行 然后我想将它存储在一个新的矩阵中,该矩阵有两列:列1=列索引,列2=包含1的行索引数组。有些列根本没有1,在这种情况下,它将是一个空数组 尝试再次执行for循环,但计算效率低下 我试着用一个更小的矩阵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
#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]
as1
是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