I need to make a grid with the numbers generated by the code, but I'm not understanding how to align them in columns.
Is there a parameter of print or something else that could help me out?
#main()
a=0
b=0
for i in range(1, 13):
a=a+1
print(" ")
b=b+1
for f in range(1,13):
print(f*b, end=" ")
My output at the moment:
I would recommend using python's f-strings:
for i in range(1, 13):
print(''.join(f"{i*j: 4}" for j in range(1,13)))
Here's the output:
1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144
The most common form is to use almost any arbitrary expression within the curly braces. This can include dictionary values, function calls and so on. The above usage specifies formatting after the colon. The space before the 4 indicates that the fill character should be a space, and the 4 indicates that the whole expression should take up 4 characters total. For more info, check out the documentation.
Considering the width of each grid cell is stored as w, which for above snippet suffices as 4, a regularly spaced grid can be printed using
w = 4
a, b = 0, 0
for i in range(1, 13):
a, b = a+1, b+1
for f in range(1, 13):
print(('{:'+str(w)+'}').format(f*b), end='')
print('')
Its output is
1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144
You can reference keyword argument values passed to the str.format() method in the format string by name via {name}. Here's an example of doing that where the value referenced is computed (as opposed to being a constant):
mx = 12
w = len(str(mx*mx)) + 1
for b in range(1, mx+1):
for f in range(1, mx+1):
print(('{:{w}}').format(f*b, w=w), end='')
print('')
Output:
1 2 3 4 5 6 7 8 9 10 11 12
2 4 6 8 10 12 14 16 18 20 22 24
3 6 9 12 15 18 21 24 27 30 33 36
4 8 12 16 20 24 28 32 36 40 44 48
5 10 15 20 25 30 35 40 45 50 55 60
6 12 18 24 30 36 42 48 54 60 66 72
7 14 21 28 35 42 49 56 63 70 77 84
8 16 24 32 40 48 56 64 72 80 88 96
9 18 27 36 45 54 63 72 81 90 99 108
10 20 30 40 50 60 70 80 90 100 110 120
11 22 33 44 55 66 77 88 99 110 121 132
12 24 36 48 60 72 84 96 108 120 132 144
Related
This question already has answers here:
Pandas percentage of total with groupby
(16 answers)
Closed 10 months ago.
I'm trying to find the % total of the value within its respective index level, however, the current result is producing Nan values.
pd.DataFrame({"one": np.arange(0, 20), "two": np.arange(20, 40)}, index=[np.array([np.zeros(10), np.ones(10).flatten()], np.arange(80, 100)])
DataFrame:
one two
0.0 80 0 20
81 1 21
82 2 22
83 3 23
84 4 24
85 5 25
86 6 26
87 7 27
88 8 28
89 9 29
1.0 90 10 30
91 11 31
92 12 32
93 13 33
94 14 34
95 15 35
96 16 36
97 17 37
98 18 38
99 19 39
Aim:
To see the % total of a column 'one' within its respective level.
Excel example:
Current attempted code:
for loc in df.index.get_level_values(0):
df.loc[loc, 'total'] = df.loc[loc, :] / df.loc[loc, :].sum()
IIUC, use:
df['total'] = df['one'].div(df.groupby(level=0)['one'].transform('sum'))
output:
one two total
0 80 0 20 0.000000
81 1 21 0.022222
82 2 22 0.044444
83 3 23 0.066667
84 4 24 0.088889
85 5 25 0.111111
86 6 26 0.133333
87 7 27 0.155556
88 8 28 0.177778
89 9 29 0.200000
1 90 10 30 0.068966
91 11 31 0.075862
92 12 32 0.082759
93 13 33 0.089655
94 14 34 0.096552
95 15 35 0.103448
96 16 36 0.110345
97 17 37 0.117241
98 18 38 0.124138
99 19 39 0.131034
I am comparing the contours of letters and have several cases of unexpected results. The most confusing to me is how X and N are being identified as best matches.
In the images below, yellow represents the unknown shape and blue represents candidate shapes. The white numbers are the result returned by cv.matchShapes using CONTOURS_MATCH_I3. (I've tried the other matching methods and just get similar odd results but with a different set of letters.)
Below shows X matching N better than X
Below shows N matching X better than N
At the end of the post are the raw data and below is a chart of the the data.
I can't come up with a rotation, scale, or skew to show that this is an optical illusion. I'm not suggesting there is an issue in matchShapes but rather an issue in my understanding of Hu moments.
I'd appreciate if someone would take a moment (pun intended) and explain how cv.matchShapes is producing these results.
--- edited ----
The images below are the result of using poly-filled shapes. I am still baffled how these letters match better than the correct ones.
target_letter
33 23
32 24
30 24
28 26
28 30
29 31
29 32
31 34
31 35
33 37
33 38
36 41
36 42
38 44
38 47
35 50
35 51
33 53
33 54
30 57
30 58
28 60
28 61
27 62
27 67
29 69
34 69
38 65
38 64
40 62
40 61
42 59
42 58
46 54
47 54
49 56
49 57
51 59
51 60
53 62
53 63
56 66
56 67
58 69
63 69
65 67
65 60
63 58
63 57
60 54
60 53
58 51
58 50
55 47
55 44
57 42
57 41
61 37
61 36
64 33
64 32
65 31
65 25
64 24
62 24
61 23
60 24
58 24
55 27
55 28
52 31
52 32
50 34
50 35
47 38
45 36
45 35
41 31
41 30
40 29
40 28
38 26
38 25
37 24
35 24
34 23
candidateLetter N
10 3
9 4
7 4
6 5
5 5
5 6
4 7
4 9
3 10
3 44
4 45
4 47
6 49
12 49
13 48
13 47
14 46
14 23
15 22
17 24
17 25
21 29
21 30
24 33
24 34
27 37
27 38
31 42
31 43
34 46
34 47
35 48
36 48
37 49
43 49
45 47
45 6
43 4
38 4
36 6
36 8
35 9
35 27
36 28
36 29
34 31
33 30
33 29
31 27
31 26
27 22
27 21
24 18
24 17
21 14
21 13
18 10
18 9
13 4
11 4
candidateLetter X
10 2
9 3
7 3
6 4
6 6
5 7
5 8
6 9
6 11
8 13
8 14
10 16
10 17
14 21
14 22
16 24
16 25
13 28
13 29
10 32
10 33
7 36
7 37
5 39
5 40
4 41
4 46
6 48
11 48
15 44
15 43
17 41
17 40
19 38
19 37
21 35
21 34
23 32
26 35
26 36
28 38
28 39
30 41
30 42
33 45
33 46
35 48
40 48
42 46
42 39
40 37
40 36
37 33
37 32
34 29
34 28
32 26
32 23
34 21
34 20
37 17
37 16
41 12
41 11
42 10
42 4
41 3
39 3
38 2
37 3
35 3
32 6
32 7
29 10
29 11
27 13
27 14
24 17
21 14
21 13
18 10
18 9
17 8
17 7
15 5
15 4
14 3
12 3
11 2
I have DataFrame from 1 to 80 numbers how can i get randomly 20 elements and save result to another DataFrame? I cant save every list like a row. Its saving elements like a columns. In the future i want to try predict every radom elements with sklearn
a = np.arange(1,81).reshape(8,10)
pd.DataFrame(a)
I must to get 20 unique numbers and write it one row. For example in python:
from random import sample
for x in range(1,20):
i=sample(range(1,81), k=20)
i.sort()
print(x,'-',i)`
It return as list [1,3,5,8,34,45,12,76,45...] 20 elements and i want its look like :
0 1 2 3 4 5 6 7 8 9 10 11 12 ... 20
0 1 5 10 14 20 55 67 34 ...... 20 elements
1
.
.
Use df.sample() to get samples of data frm a dataframe:
a = np.arange(1,81).reshape(8,10)
df = pd.DataFrame(a)
df1= df.sample(frac=.25)
>>df1
0 1 2 3 4 5 6 7 8 9
5 51 52 53 54 55 56 57 58 59 60
3 31 32 33 34 35 36 37 38 39 40
For a random permutation np.random.permutation():
df.iloc[np.random.permutation(len(df))].head(2)
0 1 2 3 4 5 6 7 8 9
6 61 62 63 64 65 66 67 68 69 70
1 11 12 13 14 15 16 17 18 19 20
EDIT : To get 20 elements in a list use:
import itertools
list(itertools.chain.from_iterable(df.sample(frac=.25).values))
#[71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
frac=.25 means 25% of the data, since you have used 80 elements 25% gives you 20 elements, you can adjust the fraction depending on you many elements you have and how many you want.
EDIT1: Further to your edit in the question: print(df.values) gives you an array:
[[ 1 2 3 4 5 6 7 8 9 10]
[11 12 13 14 15 16 17 18 19 20]
[21 22 23 24 25 26 27 28 29 30]
[31 32 33 34 35 36 37 38 39 40]
[41 42 43 44 45 46 47 48 49 50]
[51 52 53 54 55 56 57 58 59 60]
[61 62 63 64 65 66 67 68 69 70]
[71 72 73 74 75 76 77 78 79 80]]
You would require to shuffle this array using np.random.shuffle , in this case , do it on df.T.values since you also want to shuffle columns:
np.random.shuffle(df.T.values)
Then do a reshape:
df1 = pd.DataFrame(np.reshape(df.values,(4,20)))
>>df1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 4 3 10 2 8 7 1 5 6 9 14 13 20 12 18 17 11 15 16 19
1 24 23 30 22 28 27 21 25 26 29 34 33 40 32 38 37 31 35 36 39
2 44 43 50 42 48 47 41 45 46 49 54 53 60 52 58 57 51 55 56 59
3 64 63 70 62 68 67 61 65 66 69 74 73 80 72 78 77 71 75 76 79
This is a simple way using existing stackoverflow answers:
1- flatten the array so it looks more like a list, will allow you to deal with only one index instead of dealing with two array indexes
https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.ndarray.flatten.html
aflat = a.flatten()
2- Choose random items from the flattened array any of the answers here
How to randomly select an item from a list?
3- With the selected data, build your dataframe
You can also use numpy.random.choice and you can specify exact rows you want from the sample:
In [263]: a = np.arange(1,81).reshape(8,10)
In [265]: b = pd.DataFrame(a)
In [268]: b.iloc[np.random.choice(np.arange(len(b)), 5, False)]
Out[268]:
0 1 2 3 4 5 6 7 8 9
5 51 52 53 54 55 56 57 58 59 60
7 71 72 73 74 75 76 77 78 79 80
3 31 32 33 34 35 36 37 38 39 40
1 11 12 13 14 15 16 17 18 19 20
4 41 42 43 44 45 46 47 48 49 50
You can change 5 to 20 for your purpose. You need not worry about the percentile.
The following code prints out number sequences up to around 100 from a list. A fair amount of the sequences print out above 100. I want to know how to only print out the numbers that add up to 100 on the button. I have tried printing the results to a list without luck. I tried putting in if and else statements to filter the results but with no luck. I looked at list comprehensions but I know those don't use while loops and so I don't know how to get the same results with a for loop. The only information I can seem to find online is basic lessons on how to use a while loop and just printing a list of numbers out. I could not find anything about how to sort a list of numbers printed.
Here is the code:
import itertools
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in list1:
a = 0
num1 = 2
num2 = i
seq = ([a])
it = itertools.cycle((num1,num2))
while a < 100:
a += next(it)
print(a, end = " ")
seq.append(a)
print()
print("Here are the numbers", num1, "&", num2, "added together in a sequence")
print()
Output:
2 3 5 6 8 9 11 12 14 15 17 18 20 21 23 24 26 27 29 30 32 33 35 36 38 39 41 42 44 45 47 48 50 51 53 54 56 57 59 60 62 63 65 66 68 69 71 72 74 75 77 78 80 81 83 84 86 87 89 90 92 93 95 96 98 99 101
Here are the numbers 2 & 1 added together in a sequence
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100
Here are the numbers 2 & 2 added together in a sequence
2 5 7 10 12 15 17 20 22 25 27 30 32 35 37 40 42 45 47 50 52 55 57 60 62 65 67 70 72 75 77 80 82 85 87 90 92 95 97 100
Here are the numbers 2 & 3 added together in a sequence
2 6 8 12 14 18 20 24 26 30 32 36 38 42 44 48 50 54 56 60 62 66 68 72 74 78 80 84 86 90 92 96 98 102
Here are the numbers 2 & 4 added together in a sequence
2 7 9 14 16 21 23 28 30 35 37 42 44 49 51 56 58 63 65 70 72 77 79 84 86 91 93 98 100
Here are the numbers 2 & 5 added together in a sequence
2 8 10 16 18 24 26 32 34 40 42 48 50 56 58 64 66 72 74 80 82 88 90 96 98 104
Here are the numbers 2 & 6 added together in a sequence
2 9 11 18 20 27 29 36 38 45 47 54 56 63 65 72 74 81 83 90 92 99 101
Here are the numbers 2 & 7 added together in a sequence
2 10 12 20 22 30 32 40 42 50 52 60 62 70 72 80 82 90 92 100
Here are the numbers 2 & 8 added together in a sequence
2 11 13 22 24 33 35 44 46 55 57 66 68 77 79 88 90 99 101
Here are the numbers 2 & 9 added together in a sequence
2 12 14 24 26 36 38 48 50 60 62 72 74 84 86 96 98 108
Here are the numbers 2 & 10 added together in a sequence
What I want is:
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100
Here are the numbers 2 & 2 added together in a sequence
2 5 7 10 12 15 17 20 22 25 27 30 32 35 37 40 42 45 47 50 52 55 57 60 62 65 67 70 72 75 77 80 82 85 87 90 92 95 97 100
Here are the numbers 2 & 3 added together in a sequence
2 7 9 14 16 21 23 28 30 35 37 42 44 49 51 56 58 63 65 70 72 77 79 84 86 91 93 98 100
Here are the numbers 2 & 5 added together in a sequence
2 10 12 20 22 30 32 40 42 50 52 60 62 70 72 80 82 90 92 100
Here are the numbers 2 & 8 added together in a sequence
Any and all help on this will be greatly appreciated.
Well, you only know if your sequence addition adds up to 100 once you are done, so you can't start printing before that point. This should do the job:
import itertools
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in list1:
a = 0
num1 = 2
num2 = i
seq = ([a])
it = itertools.cycle((num1,num2))
while a < 100:
a += next(it)
seq.append(a)
if seq[-1] == 100: # -1 as an index gets the last entry in a list
print(" ".join([str(val) for val in seq]))
print("Here are the numbers", num1, "&", num2, "added together in a sequence")
print()
I have a question using matplotlib and imshow. I want to plot in the same figure four "matrices", using imshow, and I need the gradient to be between [0, 1]. I also need to normalize the data with the following formula:
data_norm = data * 2/400
So far I have this:
from matplotlib import mpl,pyplot
import numpy as np
zvals = np.loadtxt("sharedGradient.txt")
img = pyplot.imshow(zvals,interpolation='nearest')
pyplot.colorbar(img)
pyplot.show()
The data is in .txt files, but this is a sample of data:
61 62 63 64 65 66 67 6 5 83 82 81 28 29 30 33 34 35 36 37
60 13 12 11 10 9 8 7 4 3 2 7 27 76 31 32 69 42 41 38
59 14 15 16 17 18 69 12 11 10 1 0 26 75 74 73 70 43 40 39
58 57 56 41 40 19 70 71 72 73 4 3 25 79 133 72 71 44 61 62
160 161 55 42 39 20 21 107 114 0 1 2 24 51 52 47 46 45 60 108
62 61 54 43 38 37 22 35 38 37 36 35 23 50 49 48 57 58 59 0
63 64 53 44 25 24 23 34 31 32 33 34 22 51 56 55 56 108 107 1
203 65 52 45 26 31 24 33 30 33 34 20 21 52 53 54 55 109 106 2
202 66 51 46 27 30 25 28 29 17 18 19 38 37 36 35 111 110 105 3
156 199 50 47 28 29 26 27 28 16 30 54 50 51 52 34 112 103 104 4
121 120 49 48 28 29 46 45 27 15 39 55 49 54 53 33 113 102 6 5
114 113 112 109 27 30 31 12 13 14 40 41 46 55 31 32 120 101 7 8
3 4 5 6 15 0 10 11 25 35 40 42 45 48 30 29 28 100 99 9
2 1 0 3 2 1 2 77 32 33 34 45 46 57 67 68 27 26 25 10
9 6 5 0 1 7 80 81 31 30 35 44 60 58 59 69 70 23 24 11
10 2 3 4 5 6 79 82 83 29 36 43 42 41 60 65 66 22 21 12
11 1 11 10 21 20 23 67 66 28 37 38 39 40 61 64 67 92 20 13
12 0 14 15 20 70 7 6 26 27 80 77 76 73 62 63 68 91 19 14
13 15 51 18 19 71 8 5 4 3 2 82 83 84 71 70 69 90 18 15
14 14 13 12 11 10 9 128 129 0 1 146 147 85 86 87 88 89 17 16
My issue is that I can't get the gradient to be between [0, 1] and I can't put different plots in the same figure. Hope somebody can help.
After you normalize the data the gradient is already adjusted from 0 to 1
to separate the imshow graphs simply add subplots to the figures: plt.subplot(number of rows, number of columns, graph number)
import matplotlib.pyplot as plt
import numpy as np
zvals = np.loadtxt("sharedGradient.txt")
zvals = zvals/200
plt.subplot(2,2,1)
img = plt.imshow(zvals,interpolation='nearest')
plt.colorbar(img)
plt.subplot(2,2,2)
img = plt.imshow(zvals)
plt.colorbar(img)
plt.subplot(2,2,3)
img = plt.imshow(zvals)
plt.colorbar(img)
plt.subplot(2,2,4)
img = plt.imshow(zvals)
plt.colorbar(img)
plt.show()
If you're also trying to make the axis range from 0 to 1 then use the extent=(0,1,0,1) inside imshow()