Python:一种更像Pythonic的方式来循环网格分类



我有一个 11 x 11 大小的网格,放置在散点图上。散点图由 100 个随机生成的对组成。在每个格网空间中,都有一个分类类型,其中:

类型 A 在 X 轴和 Y 轴上都大于 0,但小于 0.5,B 型在 X 轴和 Y 轴上都大于 0.5,但小于 1.5等。。。

我想知道每个网格空间中有多少个点,以及该网格空间中存在的对。这部分不是问题,我只是想知道是否有一种更pythonic的方式来编写我的循环,因为我不想为每个网格空间编写if语句。

我的脚本如下:

    TypeA = []
    TypeB = []
    fig = plt.figure()
    ax = fig.gca()
    ax.set_xticks(np.arange(0.5, 10.5, 1))
    ax.set_yticks(np.arange(0.5, 10.5, 1))
    for ii in range(100):
        RNumX = randint(0, 10)
        RNumY = randint(0, 10)
        print RNumX, RNumY
        hold(True)
        plot1 = plt.scatter(RNumX, RNumY)
        if RNumX >= 0 and RNumX < 0.5:
            if RNumY >= 0 and RNumY < 0.5:
                PairA = (RNumX, RNumY)
                TypeA.append(PairA)
            elif RNumY >= 0.5 and RNumY < 1.5:
                PairB = (RNumX, RNumY)
                TypeB.append(PairB)
    SumA = len(TypeA)
    SumB = len(TypeB)
    print TypeA, SumA
    print TypeB, SumB
    plt.grid()
    plt.show()  

你可以让 Type 一个矩阵,并对值进行舍入以查找索引:

from random import random
# An 11 x 11 matrix of lists
Type = 11 * (11 * ([],),)
fig = plt.figure()
ax = fig.gca()
ax.set_xticks(np.arange(0.5, 10.5, 1))
ax.set_yticks(np.arange(0.5, 10.5, 1))
for ii in range(100):
    # If you want to use floats in stead of ints
    RNumX = 0.5 + 10 * random()
    RNumY = 0.5 + 10 * random()
    print RNumX, RNumY
    hold(True)
    plot1 = plt.scatter(RNumX, RNumY)
    # Round the coordinates to find the indices
    Type[int(RNumX + 0.5)][int(RNumY + 0.5)].append((RNumX, RNumY))
# Print all buckets as your snippet implies
for x in Type:
    for y in x:
        print y, len(y)
# Print only buckets with both values in the same range as your question implies
for x in range(11):
    print Type[x][x], len(Type[x][x])
plt.grid()
plt.show() 
您可以使用

bisect模块来避免这些if语句。这是一个快速而肮脏的例子。

from functools import total_ordering
import bisect
@total_ordering
class Point:
  def __init__(self, X, Y):
    self.X = X
    self.Y = Y
  def __eq__(self, other):
    return self.X == other.X and self.Y == other.Y
  def __lt__(self, other):
    return self.X < other.X and self.Y < other.Y
print [(float(x)/2, float(x)/2) for  x in xrange(0, 23)]
[(0.0, 0.0), (0.5, 0.5), (1.0, 1.0), (1.5, 1.5), (2.0, 2.0), (2.5, 2.5), (3.0, 3.0), (3.5, 3.5), (4.0, 4.0), (4.5, 4.5), (5.0, 5.0), (5.5, 5.5), (6.0, 6.0), (6.5, 6.5), (7.0, 7.0), (7.5, 7.5), (8.0, 8.0), (8.5, 8.5), (9.0, 9.0), (9.5, 9.5), (10.0, 10.0), (10.5,

10.5), (11.0, 11.0)]

points = [Point(float(x)/2, float(x)/2) for  x in xrange(0, 23)]
types = [chr(x) for x in xrange(65, 91)]
print types

["A"、"B"、"C"、"D"、"E"、"F"、"G"、"H"、"I"、"J"、"K"、"L"、"M"、"N"、"O"、"P"、"Q"、"R"、"S"、"T"、"U"、"V"、"W"、"X"、"Y"、"Z"]

print types[bisect.bisect(points, Point(0.1, 0.1)) - 1]

一个

print types[bisect.bisect(points, Point(0.6, 0.6)) - 1]

最新更新