Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.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_Numpy - Fatal编程技术网

Python 创建一个循环,在数据集的所有项上运行函数(参数是数据集的索引)?

Python 创建一个循环,在数据集的所有项上运行函数(参数是数据集的索引)?,python,numpy,Python,Numpy,所以我有一个函数: def connection(n,m,r): is_connected = ((x[n]-x[m])**2 + (y[n]-y[m])**2)**0.5 if is_connected < 2*r: return n + " " + "connects with" + " " + m else: return "no connection" 由于数组基本

所以我有一个函数:

def connection(n,m,r):
          is_connected = ((x[n]-x[m])**2 + (y[n]-y[m])**2)**0.5
          if is_connected < 2*r:
              return n + " " + "connects with" + " " + m
          else:
              return "no connection"
由于数组基本上是10组坐标,我从中产生了两个列表,x和y(x是数组的第一列,y是第二列)。m和n是这些列表中的索引。因此,n和m对应于数组中的索引,但我不确定如何对应


我现在一直在做的是手动输入索引,以查看此数组中的任意两个圆是否连接-是否有一个-for循环可以更有效地执行此操作?

一个简单的示例是:

# m is your array
rows = m.shape[0]
for x in range(rows):
    for y in range(rows)[x+1:]:
        # x, y correspond to indices of two circles
        conn = connection(x, y, r)
你可以用

为此,只需更改连接以接受圆作为其参数,并将
r
作为圆的一部分

def connection(circle):
    n, m, r = circle
    is_connected = ((x[n]-x[m])**2 + (y[n]-y[m])**2)**0.5
    if is_connected < 2*r:
        return n + " " + "connects with" + " " + m
    else:
        return "no connection"
然后简单地这样做:

map(connection, circles)
如果r是外部的,或者是成员,则您希望使用以下选项:

def connection(coord):
    n, m = coord
    is_connected = ((x[n]-x[m])**2 + (y[n]-y[m])**2)**0.5
    if is_connected < 2*r:
        return n + " " + "connects with" + " " + m
    else:
        return "no connection"

coords = array([
   [ 0.31730234,  0.73662906],
   [ 0.54488759,  0.09462212],
   [ 0.07500703,  0.36148366],
   [ 0.33200281,  0.04550565],
   [ 0.3420866 ,  0.9425797 ],
   [ 0.36115391,  0.16670599],
   [ 0.95586938,  0.52599398],
   [ 0.13707665,  0.6574444 ],
   [ 0.77766138,  0.56875582],
   [ 0.79618595,  0.7139309 ]])

map(connection, coords)

无论如何,你应该用不同的方式做事。不幸的是,速度快得多的
cKDTree
没有必要的功能,但即使是另一个
KDTree
也应该给您带来巨大的速度提升(并更优雅地解决它)

不幸的是,虽然它没有使用
cKDTree
,但这仍然为您节省了
O(N^2)
复杂性。。。当然,如果
len(圆圈)
很小,这并不重要,但是您可以使用广播(或者
distance\u matrix
from
scipy.space
):

distance=np.sqrt(((圆[:,无,:]-圆)**2.sum(-1))
连接=距离<(2*r)
#如果需要此处的列表/数组列表,可以执行以下操作:
连接=[np.flatnonzero(c)表示连接中的c]

但是请注意,第二种方法是一个内存消耗大的怪物,只有当
圆圈
很小时才有用。

在回顾了您的一些回答之后,我给您写了一个新的答案,它完全改变了您的代码

def check_overlap(circleA, circleB, r):
    # your code.
    # in each circle you have [x-coord, y-coord]

circles = [
    [0.34, 0.74], [0.27, 0.19],
    [0.24. 0.94], [0.64, 1.42]]

for a, b in ((a,b) for a in circles for b in circles):
    if a != b:
        check_overlap(a, b, r)
这清楚地表明了您在代码中所做的事情,python完全是关于可读性的


注意:最后一个函数与使用相同,但没有导入它。

编辑:刚刚实现,下面是seberg最后一个方法的扩展版本

如果您的数据集很小,比如在(非常)几千个元素中,您可以使用numpy强制执行以下操作:

import numpy as np
n = 10 # the number of circles
circles = np.random.rand(n, 2) # the array of centers
distances = circles.reshape(n, 1, 2) - circles.reshape(1, n, 2)
# distances now has shape (n, n, 2)
distances = np.sqrt(np.sum(distances**2, axis=2))
# distances now has shape (n, n)
# distances[i, j] holds the distance between the i-th and j-th circle centers
当您要检查哪些半径圆
r
重叠时,可以执行以下操作:

r = 0.1
overlap = distances < 2 * r
# overlap[i, j] is True if the i-th and j-th circle overlap, False if not
r=0.1
重叠=距离<2*r
#如果第i个和第j个圆重叠,则重叠[i,j]为真,否则为假
这最后两行代码可以重用为所需的
r
的任何值,而无需执行上一步更密集的计算



它使用了大量不必要的内存,因此对于(中等)大的数据集,它会崩溃,但由于所有循环都是由numpy在引擎盖下运行的,因此它应该很快。

函数中的
r
是什么?数组中的每个项只有两个值。对不起,r是磁盘的半径,其中心是这些坐标。它将在整个程序中更改,这就是为什么它也是一个参数。@Amanc如果
r
在整个程序中更改,而与给定的实际坐标无关,它不应该是一个参数,它应该是一个类的成员,函数应该是类的一部分。@我们的想法是,每次运行for循环和函数时,我都会更改半径并生成不同的数据集。@Amanc在查看了您的一些回答之后。我得说你的问题一点也不清楚您需要一个函数来比较两个圆,以查看是否存在重叠。要做到这一点,您需要一组相互匹配的圆对。这应该是你的方法。谢谢你的帮助。但问题是,我的参数不是圆的坐标。我的参数实际上是两个半径相同的不同圆,另一个参数是半径。因此,我们的想法是让函数在数组中两个圆的每一个组合上循环。这有道理吗?嘿!非常感谢你的帮助。但是我遇到了这个错误:TypeError:'int'对象没有属性'getitem',看起来您试图使用整数作为列表(访问元素)。我从您的代码中看到您使用的名称是x和y,与我发布的代码中的名称相同。尝试重命名它们,因为它们似乎正在覆盖您的。哦,这是一个很好的Python式回答:)。谢谢您的帮助!当我试着运行代码时,它给了我一个关于-if段格式的问题?换句话说,它说我不能添加字符串和变量?这是真的,还是我的解释器出了问题?而且,n和m不是圆中的x和y坐标-它们实际上是对应于两个不同圆的索引。抱歉不清楚。@Amanc没有看到实际的错误,stacktrace,我无法告诉您实际的问题。但你永远不能在非字符串中添加字符串。我想我已经解决了这个问题。谢谢但是,这个函数告诉我两个[i]圆是否连接-m和n不是圆的x和y坐标,它们实际上是数组中两个不同圆对应的索引。谢谢你的帮助。我得到了这个错误:名称错误:名称“x_点”没有定义谢谢!不幸的是,由于r未定义,我仍然收到一个命名错误,因此x_点和y_点未定义,代码不起作用。@Amanc好吧,
r
是半径(或者可能是
2*r
),定义它是您的工作。非常优雅的解决方案,谢谢,但这有点让我不知所措,因为我的python经验非常有限。我试着把它分解,帮助自己一点一点地理解它,所以谢谢你提高了我的能力!非常感谢。这看起来很棒。但有一件事;我正在使用numpy.random生成一个数组,这个数组的中心坐标是,r对于所有的
from scipy.spatial import KDTree
from itertools import chain

tree = KDTree(circles)

# unfortunatly only a list of lists, because there may be a different amount
# also the point itself is included every time.
connections = tree.query_ball_tree(tree, 2*r)

# if all you want is a list of lists of what connects with what
# connections is already what you need. The rest creates a connectivity matrix:    

repeats = [len(l) for l in connections]
x_point = np.arange(len(circles)).repeat(repeats)
y_point = np.fromiter(chain(*connections), dtype=np.intp)

# or construct a sparse matrix here instead, scipy.sparse has some graph tools
# maybe it even has a better thing to do this.
connected = np.zeros((len(circles),) * 2, dtype=bool)
connected[x_point, y_point] = True
distances = np.sqrt(((circles[:,None,:] - circles)**2).sum(-1))
connected = distances < (2 * r)

# if you need the list of lists/arrays here you can do:
connections = [np.flatnonzero(c) for c in connected]
def check_overlap(circleA, circleB, r):
    # your code.
    # in each circle you have [x-coord, y-coord]

circles = [
    [0.34, 0.74], [0.27, 0.19],
    [0.24. 0.94], [0.64, 1.42]]

for a, b in ((a,b) for a in circles for b in circles):
    if a != b:
        check_overlap(a, b, r)
import numpy as np
n = 10 # the number of circles
circles = np.random.rand(n, 2) # the array of centers
distances = circles.reshape(n, 1, 2) - circles.reshape(1, n, 2)
# distances now has shape (n, n, 2)
distances = np.sqrt(np.sum(distances**2, axis=2))
# distances now has shape (n, n)
# distances[i, j] holds the distance between the i-th and j-th circle centers
r = 0.1
overlap = distances < 2 * r
# overlap[i, j] is True if the i-th and j-th circle overlap, False if not