Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 遍历一维Numpy数组进行聚类_Python_Arrays_Numpy_Traversal - Fatal编程技术网

Python 遍历一维Numpy数组进行聚类

Python 遍历一维Numpy数组进行聚类,python,arrays,numpy,traversal,Python,Arrays,Numpy,Traversal,我有一个一维numpy数组,其中每个元素的值I指向数组中的另一个索引。每个群集中心都有一个唯一的负值(整数值)。目标是将每个元素分配给一个集群 范例 # Generated/pre-computed elsewhere a = np.array([6, 8, 1, -1, 0, 3, -2, 4, -3, 10, 5]) 因此,簇中心是元素3、6和8(因为它们具有负值),它们分别被标记为簇-1、-2和-3。那么,自从 a[0] = 6 --> a[6] = -2, 然后可以将[0]指

我有一个一维numpy数组,其中每个元素的值I指向数组中的另一个索引。每个群集中心都有一个唯一的负值(整数值)。目标是将每个元素分配给一个集群

范例

# Generated/pre-computed elsewhere
a = np.array([6, 8, 1, -1, 0, 3, -2, 4, -3, 10, 5])
因此,簇中心是元素3、6和8(因为它们具有负值),它们分别被标记为簇-1、-2和-3。那么,自从

a[0] = 6 --> a[6] = -2, 
然后可以将[0]指定为-2。同样,由于

a[5] = 3 --> a[3] = -1,
然后可以将[5]指定为-1。按照此逻辑,所有元素都可以分配给集群中心。生成的数组将是:

[-2, -3, -3, -1, -2, -1, -2, -2, -3, -1, -1]
我知道如何在纸上实现这一点,但我不知道如何在代码中实现这一点,也不知道如何在numpy中使用矢量化代码

更新:根据unutbu下面的回答,我将while循环替换为for循环,以避免无休止的while循环:

a = np.array([6, 8, 1, -1, 0, 3, -2, 4, -3, 10, 5])
for i in range(len(a)):
    mask = a >= 0
    if not mask.any(): break
    a[mask] = a[a[mask]]
我们不知道找到集群中心需要多少“跳跃”。因此,我们必须进行一些迭代,并检查我们是否已到达群集中心:

import numpy as np
a = np.array([6, 8, 1, -1, 0, 3, -2, 4, -3, 10, 5])

for i in a:
    mask = a>=0
    # We can stop when all the values in `a` are negative
    if not mask.any(): break
    # perform a hop
    a[mask] = a[a[mask]]

print(a)
屈服

[-2 -3 -3 -1 -2 -1 -2 -2 -3 -1 -1]

要了解发生了什么,可以更清楚地看到
a的一个更简单的值:

a = np.arange(-1, 10)
print(a)
for i in a:
    mask = a>=0
    # We can stop when all the values in `a` are negative
    if not mask.any(): break
    # perform a hop
    a[mask] = a[a[mask]]
    print(a)
印刷品

[-1  0  1  2  3  4  5  6  7  8  9]
[-1 -1  0  1  2  3  4  5  6  7  8]
[-1 -1 -1 -1  0  1  2  3  4  5  6]
[-1 -1 -1 -1 -1 -1 -1 -1  0  1  2]
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
在这里,我们可以清楚地看到每个索引处的值(即 产量)正在下降。您可能期望值减少1,但是 事实上,由于 以前啤酒花的效果

更一般地说,让
G
成为跳到同一集群的索引序列 价值循环的一个不变量是G中的值映射到G中的值。 此外,在每个索引处,在每次迭代中,距离 簇值减小(或为零)。这两个事实加在一起意味着 算法收敛到一个固定点

同样,在每次迭代中,用集群值填充的位置的数量 呈指数增长。如果在迭代之前有
n个
位置填充了集群值,那么在跳跃之后将有
2n个
位置填充了集群值。所以收敛是指数的


在OP的带领下,我将
while True
循环更改为
for循环
。在小于
len(a)
的步骤中可以找到固定点,但是a中i的
就足够了

注意,上面的代码假设每个索引都收敛到一个集群值。如果这不是真的,那么原来的
while true
循环可能会永远循环。a
中i的
将结束,但可能不是所有集群值。说明这个问题的一个简单例子是
A=np.array([1,0])


有趣的是,“简单示例”
np.arange(-1,10)
也是最坏的情况 根据长度为11的数组所需的最大迭代次数的场景。 由于集群值的数量增长为2**n,因此循环最多需要
log2(len(a))
迭代。因此,我们可以编写一个函数,当
a
包含无限个循环时,该函数将返回集群值或引发ValueError:

def converge(a):
    for i in range(int(np.log2(len(a)))+1):
        mask = a>=0
        # We can stop when all the values in `a` are negative
        if not mask.any(): break
        # perform a hop
        a[mask] = a[a[mask]]
    else:
        # for-loop completed without reaching break
        mask = a>=0
        if mask.any(): 
            raise ValueError('{!r} contains infinite cycles'.format(a))
    return a
我们不知道找到集群中心需要多少“跳跃”。因此,我们必须进行一些迭代,并检查我们是否已到达群集中心:

import numpy as np
a = np.array([6, 8, 1, -1, 0, 3, -2, 4, -3, 10, 5])

for i in a:
    mask = a>=0
    # We can stop when all the values in `a` are negative
    if not mask.any(): break
    # perform a hop
    a[mask] = a[a[mask]]

print(a)
屈服

[-2 -3 -3 -1 -2 -1 -2 -2 -3 -1 -1]

要了解发生了什么,可以更清楚地看到
a的一个更简单的值:

a = np.arange(-1, 10)
print(a)
for i in a:
    mask = a>=0
    # We can stop when all the values in `a` are negative
    if not mask.any(): break
    # perform a hop
    a[mask] = a[a[mask]]
    print(a)
印刷品

[-1  0  1  2  3  4  5  6  7  8  9]
[-1 -1  0  1  2  3  4  5  6  7  8]
[-1 -1 -1 -1  0  1  2  3  4  5  6]
[-1 -1 -1 -1 -1 -1 -1 -1  0  1  2]
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
在这里,我们可以清楚地看到每个索引处的值(即 产量)正在下降。您可能期望值减少1,但是 事实上,由于 以前啤酒花的效果

更一般地说,让
G
成为跳到同一集群的索引序列 价值循环的一个不变量是G中的值映射到G中的值。 此外,在每个索引处,在每次迭代中,距离 簇值减小(或为零)。这两个事实加在一起意味着 算法收敛到一个固定点

同样,在每次迭代中,用集群值填充的位置的数量 呈指数增长。如果在迭代之前有
n个
位置填充了集群值,那么在跳跃之后将有
2n个
位置填充了集群值。所以收敛是指数的


在OP的带领下,我将
while True
循环更改为
for循环
。在小于
len(a)
的步骤中可以找到固定点,但是a中i的
就足够了

注意,上面的代码假设每个索引都收敛到一个集群值。如果这不是真的,那么原来的
while true
循环可能会永远循环。a
中i的
将结束,但可能不是所有集群值。一个简单的例子说明了问题是
A=np.array([1,0])


有趣的是,“简单示例”
np.arange(-1,10)
也是最坏的情况 根据长度为11的数组所需的最大迭代次数的场景。 由于集群值的数量增长为2**n,因此循环最多需要
log2(len(a))
迭代。因此,我们可以编写一个函数,当
a
包含无限个循环时,该函数将返回集群值或引发ValueError:

def converge(a):
    for i in range(int(np.log2(len(a)))+1):
        mask = a>=0
        # We can stop when all the values in `a` are negative
        if not mask.any(): break
        # perform a hop
        a[mask] = a[a[mask]]
    else:
        # for-loop completed without reaching break
        mask = a>=0
        if mask.any(): 
            raise ValueError('{!r} contains infinite cycles'.format(a))
    return a

你试过什么吗?如果是,请发布。您的流程似乎不适用于
a[9]
@wwii:a[9]-->a[10]-->a[5]-->a[3]-->-1您尝试过什么吗?如果是这样,请发布。您的流程似乎不适用于
a[9]
@wwii:a[9]-->a[10]-->a[5]-->a[3]-->-1每个跃点都会修改元素/项目,当在后续跃点中引用修改的元素时,是否保证在该点包含正确的值?这似乎应该适用于这个例子,但我就是看不透它。@wwii: