Python: A More Pythonic Path to Loops

I have an 11 by 11 grid that fits above the scatter chart. The scatter plot consists of 100 randomly generated pairs. Inside each grid space there is a classification type, where:

Type A is greater than 0, but less than 0.5 in both axes X and Y, Type B is greater than 0.5, but less than 1.5 in both axes X and Y ect ...

I want to know how many points are inside each grid space, as well as the pairs that exist in this grid space. This part is not a problem, I just want to know if there is a more pythonic way to write my loop, since I do not want to write an if statement for each grid space.

My script looks like this:

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() 
+4
source share
2 answers

You can make matrix type and round values ​​to find your indices:

 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() 
+1
source

you can use the bisect module to avoid these if statements. Here is a quick and dirty example.

 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.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) (10.0, 10.0), (10.5, 10.0), (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] 

A

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

IN

0
source

Source: https://habr.com/ru/post/1447267/


All Articles