python创建矩阵行向量_python – 矩阵行差异,输出布尔向量

我有一个m×3矩阵A和它的行子集B(n×3).两者都是另一个大型4D矩阵的指数集;他们的数据类型是dtype(‘int64’).我想生成一个布尔向量x,其中如果B不包含行A [i,:],则x [i] = True.

A或B中没有重复的行.

我想知道在Numpy中是否有一种有效的方法可以做到这一点?我找到了一个有点相关的答案:https://stackoverflow.com/a/11903368/265289;但是,它返回实际的行(不是布尔向量).

解决方法:

除了使用np.in1d而不是np.setdiff1d之外,您可以使用与jterrace’s answer中所示相同的模式:

import numpy as np

np.random.seed(2015)

m, n = 10, 5

A = np.random.randint(10, size=(m,3))

B = A[np.random.choice(m, n, replace=False)]

print(A)

# [[2 2 9]

# [6 8 5]

# [7 8 0]

# [6 7 8]

# [3 8 6]

# [9 2 3]

# [1 2 6]

# [2 9 8]

# [5 8 4]

# [8 9 1]]

print(B)

# [[2 2 9]

# [1 2 6]

# [2 9 8]

# [3 8 6]

# [9 2 3]]

def using_view(A, B, assume_unique=False):

Ad = np.ascontiguousarray(A).view([('', A.dtype)] * A.shape[1])

Bd = np.ascontiguousarray(B).view([('', B.dtype)] * B.shape[1])

return ~np.in1d(Ad, Bd, assume_unique=assume_unique)

print(using_view(A, B, assume_unique=True))

产量

[False True True True False False False False True True]

您可以使用assume_unique = True(可以加快计算速度)

A或B中没有重复的行.

请注意A.view(…)将提出

ValueError: new type not compatible with array.

如果A.flags [‘C_CONTIGUOUS’]为False(即如果A不是C连续数组).

因此,通常我们需要在调用view之前使用np.ascontiguous(A).

作为B.M.建议,您可以使用“void”

dtype查看每一行:

def using_void(A, B):

dtype = 'V{}'.format(A.dtype.itemsize * A.shape[-1])

Ad = np.ascontiguousarray(A).view(dtype)

Bd = np.ascontiguousarray(B).view(dtype)

return ~np.in1d(Ad, Bd, assume_unique=True)

这对于整数dtypes是安全的.但请注意

In [342]: np.array([-0.], dtype='float64').view('V8') == np.array([0.], dtype='float64').view('V8')

Out[342]: array([False], dtype=bool)

因此在查看为void后使用np.in1d可能会返回不正确的数组结果

用float dtype.

以下是一些建议方法的基准:

import numpy as np

np.random.seed(2015)

m, n = 10000, 5000

# Note A may contain duplicate rows,

# so don't use assume_unique=True for these benchmarks.

# In this case, using assume_unique=False does not improve the speed much anyway.

A = np.random.randint(10, size=(2*m,3))

# make A not C_CONTIGUOUS; the view methods fail for non-contiguous arrays

A = A[::2]

B = A[np.random.choice(m, n, replace=False)]

def using_view(A, B, assume_unique=False):

Ad = np.ascontiguousarray(A).view([('', A.dtype)] * A.shape[1])

Bd = np.ascontiguousarray(B).view([('', B.dtype)] * B.shape[1])

return ~np.in1d(Ad, Bd, assume_unique=assume_unique)

from scipy.spatial import distance

def using_distance(A, B):

return ~np.any(distance.cdist(A,B)==0,1)

from functools import reduce

def using_loop(A, B):

pred = lambda i: A[:, i:i+1] == B[:, i]

return ~reduce(np.logical_and, map(pred, range(A.shape[1]))).any(axis=1)

from pandas.core.groupby import get_group_index, _int64_overflow_possible

from functools import partial

def using_pandas(A, B):

shape = [1 + max(A[:, i].max(), B[:, i].max()) for i in range(A.shape[1])]

assert not _int64_overflow_possible(shape)

encode = partial(get_group_index, shape=shape, sort=False, xnull=False)

a1, b1 = map(encode, (A.T, B.T))

return ~np.in1d(a1, b1)

def using_void(A, B):

dtype = 'V{}'.format(A.dtype.itemsize * A.shape[-1])

Ad = np.ascontiguousarray(A).view(dtype)

Bd = np.ascontiguousarray(B).view(dtype)

return ~np.in1d(Ad, Bd)

# Sanity check: make sure all the functions return the same result

for func in (using_distance, using_loop, using_pandas, using_void):

assert (func(A, B) == using_view(A, B)).all()

In [384]: %timeit using_pandas(A, B)

100 loops, best of 3: 1.99 ms per loop

In [381]: %timeit using_void(A, B)

100 loops, best of 3: 6.72 ms per loop

In [378]: %timeit using_view(A, B)

10 loops, best of 3: 35.6 ms per loop

In [383]: %timeit using_loop(A, B)

1 loops, best of 3: 342 ms per loop

In [379]: %timeit using_distance(A, B)

1 loops, best of 3: 502 ms per loop

标签:python,matrix,numpy,set-difference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值