关于Stack的第一个问题,大家好!
我有一个元组,有两个1D np矩阵,来自np.nonzero,例如:
(array([479, 479, 479, 480, 480, 480, 481, 481, 481, 482, 482, 482, 650,
650, 650, 651, 651, 651, 652, 652, 652, 653, 653, 653, 654, 654,
654, 708, 708, 708, 709, 709, 709, 710, 710, 710, 711, 711, 711,
712, 712, 712, 713, 713, 713], dtype=int64),
array([ 859, 860, 861, 859, 860, 861, 859, 860, 861, 859, 860,
861, 1045, 1046, 1047, 1045, 1046, 1047, 1045, 1046, 1047, 1045,
1046, 1047, 1045, 1046, 1047, 1039, 1040, 1041, 1039, 1040, 1041,
1039, 1040, 1041, 1039, 1040, 1041, 1039, 1040, 1041, 1039, 1040,
1041], dtype=int64))
但在我未来的使用中,这个元组会更大。我正在寻找最快的方法,只保留元组第一列中每个元素(第一个)的一个占用,并保持第二列中的第二个coordonate。另外,第一列已分类
对于我的例子,我想要这个输出:
(array([479, 480, 481, 482, 650, 651, 652, 653, 654, 708, 709, 710, 711, 712], dtype=int64),
array([861, 861, 861, 861, 1047, 1047, 1047, 1047, 1047, 1041, 1041, 1041, 1041, 1041],dtype=int64))
一个天真的解决方案可能是:
for k in range(len(nozero[0])-1):
i = nozero[0][k]
i2 = nozero[0][k+1]
j = nozero[1][k]
j2 = nozero[1][k+1]
if i != i2:
x.append(i)
y.append(j)
随时向我推荐一些有关此内容的信息,如果您有更好的想法来组织数据,请随时向我推荐! (或者如果你想要更好的解释)。
非常感谢!
答案 0 :(得分:1)
您可以在第一个阵列上使用np.diff
来查找所有首次出现的掩码。然后使用掩码简单地切割每个数组。
请注意,np.diff
会产生一个比原始数字小1的数组,因此我们预先添加1
(数组中的第一个元素始终是同类中的第一个)。
from numpy import array,int64
import numpy as np
arr1, arr2 = (array([479, 479, 479, 480, 480, 480, 481, 481, 481, 482, 482, 482, 650,
650, 650, 651, 651, 651, 652, 652, 652, 653, 653, 653, 654, 654,
654, 708, 708, 708, 709, 709, 709, 710, 710, 710, 711, 711, 711,
712, 712, 712, 713, 713, 713], dtype=int64),
array([ 859, 860, 861, 859, 860, 861, 859, 860, 861, 859, 860,
861, 1045, 1046, 1047, 1045, 1046, 1047, 1045, 1046, 1047, 1045,
1046, 1047, 1045, 1046, 1047, 1039, 1040, 1041, 1039, 1040, 1041,
1039, 1040, 1041, 1039, 1040, 1041, 1039, 1040, 1041, 1039, 1040,
1041], dtype=int64))
first_occurences_mask = np.concatenate([[1], np.diff(arr1)], axis=0) > 0
first_occurences_mask
=>
array([ True, False, False, True, False, False, True, False, False,
True, False, False, True, False, False, True, False, False,
True, False, False, True, False, False, True, False, False,
True, False, False, True, False, False, True, False, False,
True, False, False, True, False, False, True, False, False], dtype=bool)
res1, res2 = (arr1[first_occurences_mask], arr2[first_occurences_mask])
res1, res2
=>
(array([479, 480, 481, 482, 650, 651, 652, 653, 654, 708, 709, 710, 711,
712, 713]),
array([ 859, 859, 859, 859, 1045, 1045, 1045, 1045, 1045, 1039, 1039,
1039, 1039, 1039, 1039]))
(顺便说一下,这是一个非常好的第一个问题。在您发布之前,您已经阅读了规则和最佳做法,并且显示了。)
编辑(@alejandro) - 时间比较:
为了证明这种方法比@B更快。 M.,下面我对两者进行了比较:
from numpy import array,int64
import numpy as np
import time
time1 = []
time2 = []
nelements = np.logspace(1,7)
for i in nelements:
arr = np.random.randint(0,i, i)
start = time.time()
first_occurences_mask = np.concatenate([[1], np.diff(arr)], axis=0) > 0
stop = time.time()
time1.append(stop-start)
start = time.time()
np.unique(arr,return_index=True)
stop = time.time()
time2.append(stop-start)
得出以下结果:
这个图清楚地表明,对于大数组,使用连接的速度是巨大的
答案 1 :(得分:1)
使用np.unique
:
In [1]: i,j = nozeros # your two arrays.
In [3]: uniq,index,count=np.unique(i,return_index=True,return_counts=True)
uniq
中的唯一元素og:
In [4]: uniq
Out[4]:
array([479, 480, 481, 482, 650, 651, 652, 653, 654, 708, 709, 710, 711,
712, 713], dtype=int64)
如果你想要j
中的最后一个对应元素,例如你的例子:
In [5]: j[index+count-1]
Out[5]:
array([ 861, 861, 861, 861, 1047, 1047, 1047, 1047, 1047, 1041, 1041,
1041, 1041, 1041, 1041], dtype=int64)