【问题标题】:Calculating how often coordinates fall within a certain perimeter?计算坐标在某个周长内的频率?
【发布时间】:2013-04-09 19:49:15
【问题描述】:

我的意思是想象我有一个空的 100*100 数组,并且这个数组中有几千个随机位置/坐标。我需要计算这些坐标中有多少位于“直”边缘的 15 个像素内。到目前为止,我有这个代码...

import random
import pylab
import numpy                            #all import statements
pylab.close("all")

x = [(random.randint(0,100)) for i in range(3000)]      #creating list of x coordinates
y = [(random.randint(0,100)) for j in range(3000)]      #creating list of y coordinates
array=zip(x,y)                                                  #creating an array by combining the x and y coordinates
                                #end of part 1a
counter = 0                         #start of 1b
for i in range(100):
    for j in range(100):
        if i<=15 or i>=85:
                        if array[i][j]>0:
                                counter=counter+1
        elif j<=15 or j>=85:
                        if array[i][j]>0:
                                counter=counter+1

print counter,"random locations within 15 pixels of the edges"

如何更正代码?目前我收到一条错误消息,说“元组索引超出范围”我知道它引用了 if array[i][j]>0 行,但我不明白它有什么问题...

【问题讨论】:

  • zip 可能没有按照您的想法进行。它不是创建一个 100 x 100 数组,而是一个包含 100 个 (x,y) 元组的列表。
  • 那么我怎样才能纠正它,使它成为一个数组或让计数器查看元组?

标签: python arrays list tuples counter


【解决方案1】:

你已经接近了。您正在生成一个稀疏的值网格。如果您通过首先将这些元组放在字典中来迭代这些元组,您可以检查每个离散位置是否存在边缘违规。下面是一个工作示例。

edge_dist = 15
sparse_grid = collections.defaultdict(int)
for x,y in zip(x,y):
    sparse_grid[(x,y)] += 1
for i,j in sparse_grid:
    if (i <= edge_dist or i >= 100-edge_dist or 
            j <= edge_dist or j >= 100-edge_dist):
        counter += sparse_grid[(i,j)]

print "%d random locations within 15 pixels of the edges" % counter
# 1579 random locations within 15 pixels of the edges

您在您的版本中遇到的错误是因为 zip 为您提供了 x,y 的元组,而不是 x-by-y 值的网格。您可以在上面看到应该如何使用您的 zip 调用。

【讨论】:

    【解决方案2】:

    我不完全确定我是否理解您想要实现的目标,但如果您想获取 3000 个随机点并查看其中有多少在 100x100 正方形边缘的 15 个单位内,以下将工作:

    sum(not (15 < x < 85 and 15 < y < 85) for x, y in array)
    

    这利用了 Python 的布尔值 True 和 False 也具有整数值(分别为 1 和 0)这一事实。因此,您可以将Trues 和Falses 的序列相加得到真实值的计数。

    我使用了一个否定表达式,因为它允许我使用 Python 的不等式链接来进行实际的边界测试。表达式not 15 &lt; x &lt; 85 对我来说似乎比等效的x &lt;= 15 or x &gt;= 85 好得多。这可能是主观的,您的里程可能会有所不同。

    【讨论】:

    • 我不知道依赖 True 来评估为 1 是个好主意。
    • @cmd 在 Python 中它非常安全。 bool 类型是 int 的子类,True == 1 and False == 0 是其定义的基础。也许 Python 4 会打破这一点,但我不希望它在那之前的任何时候发生。
    【解决方案3】:
    x = numpy.array(x)
    y = numpy.array(y)
    counter = ((x<=15) | (y<=15) | (x>=85) | (y>=85)).sum()
    

    【讨论】:

      【解决方案4】:

      您不需要实际构建数组来计算覆盖的边缘点。如果您担心不计算相同的坐标两次,您可以使用一组删除重复项。

      cords = set(array)                                # set removes duplicates
      
      counter = 0
      for i, j in cords:  # or array if you want to count duplicates
          if i <= 15 or i >= 85 or j <= 15 or j >= 85:
              counter += 1
      
      print counter, "random locations within 15 pixels of the edges"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 1970-01-01
        • 2014-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-12
        相关资源
        最近更新 更多