piR*_*red 13 python numpy pandas
考虑排序的数组a
:
a = np.array([0, 2, 3, 4, 5, 10, 11, 11, 14, 19, 20, 20])
Run Code Online (Sandbox Code Playgroud)
如果我指定了左右三角形,
delta_left, delta_right = 1, 1
Run Code Online (Sandbox Code Playgroud)
那么这就是我期望分配集群的方式:
# a = [ 0 . 2 3 4 5 . . . . 10 11 . . 14 . . . . 19 20
# 11 20
#
# [10--|-12] [19--|-21]
# [1--|--3] [10--|-12] [19--|-21]
# [-1--|--1] [3--|--5] [9--|-11] [18--|-20]
# +--+--|--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
# [2--|--4] [13--|-15]
#
# ? ???????? ???? ? ????
# ? cluster 2 Cluster 3 ? Cluster 5
# Cluster 1 Cluster 4
Run Code Online (Sandbox Code Playgroud)
注意:尽管区间[-1, 1]
共享边缘[1, 3]
,但是两个区间都不包括相邻点,因此不构成连接它们各自的簇.
假设集群分配存储在一个名为的数组中clusters
,我希望结果看起来像这样
print(clusters)
[1 2 2 2 2 3 3 3 4 5 5 5]
Run Code Online (Sandbox Code Playgroud)
但是,假设我将左右增量更改为不同:
delta_left, delta_right = 2, 1
Run Code Online (Sandbox Code Playgroud)
这意味着它的值x
应该与区间中的任何其他点组合[x - 2, x + 1]
# a = [ 0 . 2 3 4 5 . . . . 10 11 . . 14 . . . . 19 20
# 11 20
#
# [9-----|-12] [18-----|-21]
# [0-----|--3] [9-----|-12] [18-----|-21]
# [-2-----|--1][2-----|--5] [8-----|-11] [17-----|-20]
# +--+--|--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
# [1 ----|--4] [12-----|-15]
#
# ????????????? ???? ? ????
# cluster 1 Cluster 2 ? Cluster 4
# Cluster 3
Run Code Online (Sandbox Code Playgroud)
注意:尽管区间[9, 12]
共享边缘[12, 15]
,但是两个区间都不包括相邻点,因此不构成连接它们各自的簇.
假设集群分配存储在一个名为的数组中clusters
,我希望结果如下所示:
print(clusters)
[1 1 1 1 1 2 2 2 3 4 4 4]
Run Code Online (Sandbox Code Playgroud)
我们将利用np.searchsorted
和逻辑来查找簇边缘.
首先,让我们仔细看看np.searchsorted
它的作用:
将索引查找到排序数组a中,如果在索引之前插入v中的相应元素,则将保留a的顺序.
我要做的是执行np.searchsorted
与a
使用a - delta_left
.让我们来看看delta_left = 1
# a =
# [ 0 2 3 4 5 10 11 11 14 19 20 20]
#
# a - delta_left
# [-1 1 2 3 4 9 10 10 13 18 19 19]
Run Code Online (Sandbox Code Playgroud)
-1
将被插入到位0
以维持秩序1
将被插入到位1
以维持秩序2
也将插入到位置1
,表明2
可能在同一个集群中1
3
将被插入到位置,2
表明3
可能在同一个集群中2
我们注意到,只有当一个较少元素的delta插入其当前位置时,我们才会考虑新的簇开始.
我们再次为右侧做同样的事情.不同之处在于,默认情况下,如果一堆元素相同,则np.searchsorted
假定插入值的前面.为了识别簇的末端,我想要在相同的元素之后插入.因此我会使用参数side='right'
如果是'left',则给出找到的第一个合适位置的索引.如果'正确',则返回最后一个索引.如果没有合适的索引,则返回0或N(其中N是a的长度).
现在的逻辑.只有先前的集群已经结束,集群才能开始,但第一个集群除外.然后我们将考虑第二个结果的移位版本np.searchsorted
我们现在定义我们的功能
def delta_cluster(a, dleft, dright):
# use to track whether searchsorted results are at correct positions
rng = np.arange(len(a))
edge_left = a.searchsorted(a - dleft)
starts = edge_left == rng
# we append 0 to shift
edge_right = np.append(0, a.searchsorted(a + dright, side='right')[:-1])
ends = edge_right == rng
return (starts & ends).cumsum()
Run Code Online (Sandbox Code Playgroud)
示范
左,右三角等于1和1
print(delta_cluster(a, 1, 1))
[1 2 2 2 2 3 3 3 4 5 5 5]
Run Code Online (Sandbox Code Playgroud)
左,右三角等于2和1
print(delta_cluster(a, 2, 1))
[1 1 1 1 1 2 2 2 3 4 4 4]
Run Code Online (Sandbox Code Playgroud)
额外信用
如果a
没有排序怎么办?
我将利用从这篇文章中学到的信息
def delta_cluster(a, dleft, dright):
s = a.argsort()
size = s.size
if size > 1000:
y = np.empty(s.size, dtype=np.int64)
y[s] = np.arange(s.size)
else:
y = s.argsort()
a = a[s]
rng = np.arange(len(a))
edge_left = a.searchsorted(a - dleft)
starts = edge_left == rng
edge_right = np.append(0, a.searchsorted(a + dright, side='right')[:-1])
ends = edge_right == rng
return (starts & ends).cumsum()[y]
Run Code Online (Sandbox Code Playgroud)
示范
b = np.random.permutation(a)
print(b)
[14 10 3 11 20 0 19 20 4 11 5 2]
Run Code Online (Sandbox Code Playgroud)
print(delta_cluster(a, 2, 1))
[1 1 1 1 1 2 2 2 3 4 4 4]
Run Code Online (Sandbox Code Playgroud)
print(delta_cluster(b, 2, 1))
[3 2 1 2 4 1 4 4 1 2 1 1]
Run Code Online (Sandbox Code Playgroud)
print(delta_cluster(b, 2, 1)[b.argsort()])
[1 1 1 1 1 2 2 2 3 4 4 4]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
303 次 |
最近记录: |