Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:比较两个数组的元素_Python_Arrays_Performance_Numpy - Fatal编程技术网

Python:比较两个数组的元素

Python:比较两个数组的元素,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,我想比较两个numpy数组的元素,如果坐标之间的欧氏距离小于1且时间相同,则删除其中一个数组的元素。data_CD4和data_CD8是阵列。数组的元素是带有3D坐标的列表,时间是第四个元素(numpy.array([[x,y,z,time],[x,y,z,time]…])。Co是截止点,这里是1 for i in data_CD8: for m in data_CD4: if distance.euclidean(tuple(i[:3]),tuple(m

我想比较两个numpy数组的元素,如果坐标之间的欧氏距离小于1且时间相同,则删除其中一个数组的元素。data_CD4和data_CD8是阵列。数组的元素是带有3D坐标的列表,时间是第四个元素(numpy.array([[x,y,z,time],[x,y,z,time]…])。Co是截止点,这里是1

for i in data_CD8:
        for m in data_CD4:
            if distance.euclidean(tuple(i[:3]),tuple(m[:3])) < co and i[3]==m[3] :
                data_CD8=np.delete(data_CD8, i, 0)
数据CD8中的i的
:
对于m in数据_CD4:
如果距离欧几里德(元组(i[:3]),元组(m[:3])

有没有更快的方法可以做到这一点?第一个数组有5000个元素,第二个数组有2000个元素,所以它花费了太多的时间。

如果您必须将
数据\u CD4
中的所有项目与
数据\u CD8
中的项目进行比较 在从
data\u CD8
中删除数据时,最好在每次迭代中使第二个iterable更小,这当然取决于最常见的 案例

对于数据中的m\u CD4:
对于数据_CD8中的i:
如果距离.euclidean(tuple(i[3:]),tuple(m[3:])
基于大O符号-由于这是
O(n^2)
-我看不到更快的
解决方案。

如果您必须将
数据\u CD4
中的所有项目与
数据\u CD8
在从
data\u CD8
中删除数据时,最好在每次迭代中使第二个iterable更小,这当然取决于最常见的 案例

对于数据中的m\u CD4:
对于数据_CD8中的i:
如果距离.euclidean(tuple(i[3:]),tuple(m[3:])
基于大O符号-由于这是
O(n^2)
-我看不到更快的
解决方案。

这应该是一种矢量化方法

mask1 = np.sum((data_CD4[:, None, :3] - data_CD8[None, :, :3])**2, axis = -1) < co**2
mask2 = data_CD4[:, None, 3] == data_CD8[None, :, 3]
mask3 = np.any(np.logical_and(mask1, mask2), axis = 0)
data_CD8 = data_CD8[~mask3]

C编译的代码获胜,即使添加了不必要的平方根。

这应该是一种矢量化方法

mask1 = np.sum((data_CD4[:, None, :3] - data_CD8[None, :, :3])**2, axis = -1) < co**2
mask2 = data_CD4[:, None, 3] == data_CD8[None, :, 3]
mask3 = np.any(np.logical_and(mask1, mask2), axis = 0)
data_CD8 = data_CD8[~mask3]

即使添加了不必要的平方根,C编译代码也会获胜。

这里有一种使用-

从scipy.spatial导入距离
#获取数据CD8和数据CD4的前三列之间的欧几里德距离
dists=distance.cdist(数据\u CD8[:,:3],数据\u CD4[:,:3])
#获取那些在同一距离内的距离的掩码。这将设置
#第一个条件要求发布在原始代码的循环版本中。
mask1=dists
以下是一种使用-

从scipy.spatial导入距离
#获取数据CD8和数据CD4的前三列之间的欧几里德距离
dists=distance.cdist(数据\u CD8[:,:3],数据\u CD4[:,:3])
#获取那些在同一距离内的距离的掩码。这将设置
#第一个条件要求发布在原始代码的循环版本中。
mask1=dists
应该是
[:3]
,而不是
[3:]
。如果你想用numpy进行比较,请检查:正如@trincot指出的,它必须是
距离。欧几里德(tuple(i[:3]),tuple(m[:3])
。你能确认吗?是的!你是对的。我更改了它。那应该是
[:3]
,而不是
[3:]
。如果您想使用numpy进行比较,请检查以下内容:正如@trincot指出的,它必须是距离
。你能确认一下吗?是的!你是对的。我更改了它。谢谢你的努力。我在尝试代码时遇到了这个错误:索引器:索引3284超出了大小为2587的轴0的界限很难判断没有线的错误是什么,但是请尝试
mask3
aa中的
axis=0
,正如在Divakar的回答中一样,你需要反转
mask3
啊,很好!是的,现在你的两个代码都有相同的结果。你能解释一下你的代码是什么吗?我真的很想理解:)如果原始数组有维度
(n,4)
(m,4)
在这两种情况下
mask1
mask2
都是
(n,m)
布尔数组将一个数组的每一行与另一个数组的每一行进行比较。然后使用
np.any
查找任何
数据\u CD8
行的
True
值。既然你想摆脱这些行,你
a = np.random.randint(0, 10, (100, 3))

b = np.random.randint(0, 10, (100, 3))

%timeit cdist(a,b) < 5  #Divakar's answer
10000 loops, best of 3: 133 µs per loop

%timeit np.sum((a[None, :, :] - b[:, None, :]) ** 2, axis = -1) < 25  # My answer
1000 loops, best of 3: 418 µs per loop
from scipy.spatial import distance

# Get eucliden distances between first three cols off data_CD8 and data_CD4
dists = distance.cdist(data_CD8[:,:3], data_CD4[:,:3])

# Get mask of those distances that are within co distance. This sets up the 
# first condition requirement as posted in the loopy version of original code.
mask1 = dists < co

# Take the third column off the two input arrays that represent the time values.
# Get the equality between all time values off data_CD8 against all time values
# off data_CD4. This sets up the second conditional requirement.
# We are adding a new axis with None, so that NumPY broadcasting
# would let us do these comparisons in a vectorized manner.
mask2 = data_CD8[:,3,None] == data_CD4[:,3]

# Combine those two masks and look for any match correponding to any 
# element off data_CD4. Since the masks are setup such that second axis
# represents data_CD4, we need numpy.any along axis=1 on the combined mask.
# A final inversion of mask is needed as we are deleting the ones that 
# satisfy these requirements.
mask3 = ~((mask1 & mask2).any(1))

# Finally, using boolean indexing to select the valid rows off data_CD8
out = data_CD8[mask3]