searching for numbers in a list - python

If I have output that looks like this
[[121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111],
[82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 110],
[83, 50, 49, 48, 47, 46, 45, 44, 43, 72, 109],
[84, 51, 26, 25, 24, 23, 22, 21, 42, 71, 108],
[85, 52, 27, 10, 9, 8, 7, 20, 41, 70, 107],
[86, 53, 28, 11, 2, 1, 6, 19, 40, 69, 106],
[87, 54, 29, 12, 3, 4, 5, 18, 39, 68, 105],
[88, 55, 30, 13, 14, 15, 16, 17, 38, 67, 104],
[89, 56, 31, 32, 33, 34, 35, 36, 37, 66, 103],
[90, 57, 58, 59, 60, 61, 62, 63, 64, 65, 102],
[91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101]]
how do I get it to where I can find and print a certain number and the numbers surrounding it? This is my code.
dim = 11
dx, dy = [0, 1, 0, -1], [1, 0, -1, 0]
x, y, c = 0, -1, dim**2
m = [[0 for i in range(dim)] for j in range(dim)]
for i in range(dim + dim - 1):
for j in range((dim + dim - i) // 2):
x += dx[i % 4]
y += dy[i % 4]
m[x][y] = c
c -= 1
print(m)
b = c.index(num)
print(b)
a =('\n'.join([' '.join([str(v) for v in r])for r in m]))
print(a)

Assuming that list-of-lists is called lol:-):
def neighbors(lol, anum):
for i, row in enumerate(lol[1:-1]):
try: where = row.index(anum)
except ValueError: continue
if where==0 or where==len(row)-1: continue
for j in range(i, i+3):
print(lol[j][where-1], lol[j][where], lol[j][where+1])
print()
This embodies several assumptions, such as: (A) you don't care for hits on the first or last row or column since they don't have all the neighbors you want to print, and also (B) you don't care about multiple "hits" in a single row but (C) do care about "hits" in multiple rows.
Of course all such assumptions can be changed but that requires you to be much more precise in your specs than you've been so far:-).
The print format assumes either Python 3 or a from __future__ import print_function if you're stuck with Python 2.

First in this case as c is a int value hasn't attribute index . so the following command will raise an AttributeError .
b = c.index(num)
and for get the desire result all that you need here is reversing the r list in following command , and for print you can use format :
a =('\n'.join([' '.join(["{:3}".format(v) for v in r[::-1]])for r in m]))
so the result will be :
111 112 113 114 115 116 117 118 119 120 121
110 73 74 75 76 77 78 79 80 81 82
109 72 43 44 45 46 47 48 49 50 83
108 71 42 21 22 23 24 25 26 51 84
107 70 41 20 7 8 9 10 27 52 85
106 69 40 19 6 1 2 11 28 53 86
105 68 39 18 5 4 3 12 29 54 87
104 67 38 17 16 15 14 13 30 55 88
103 66 37 36 35 34 33 32 31 56 89
102 65 64 63 62 61 60 59 58 57 90
101 100 99 98 97 96 95 94 93 92 91

Related

How to select different element of different row in numpy?

Lst's say there is a matrix A
A = [[ 34 61 29 74(17)32 72 92 93 57 ]
[(46)10 23 84 74 57 56 88 90 36 ]
[ 23(83)58 42 93 54 82 48 63 73 ]]
and a vector b of size 3
b = [4, 0, 1]
Does numpy has any function that would do the following job?
>>>A.choose_row_wise(b)
would output:
[17, 46, 83]
With numpy.take_along_axis:
b = np.array([4, 0, 1])
res = np.take_along_axis(A, b[:, None], axis=1).flatten()
print(res)
[17 46 83]
This can be done using indexing.
import numpy as np
A = np.array([[34, 61, 29, 74, 17, 32, 72, 92, 93, 57],[46, 10, 23, 84, 74, 57, 56, 88, 90, 36],[23, 83, 58, 42, 93, 54, 82, 48, 63, 73]])
b = np.array([4, 0, 1])
result = A[np.arange(len(b)), b]
[17 46 83]
Maybe you can use the following code:
import numpy as np
A = np.array([[34,61,29,74,(17),32,72,92,93,57],[(46),10,23,84,74,57,56,88,90,36],[23,(83),58,42,93,54,82,48,63,73]])
b = [4, 0, 1]
print([A[b.index(i), i] for i in b])

How to print a list into 4 columns horizontally and vertically (transposed)?

I have a list
list = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 39, 44, 42, 40, 43, 47, 45, 57, 52, 75, 73, 86, 78, 70, 77, 87, 79, 113, 96, 147, 141, 170, 150, 130, 145, 167, 147, 225, 184]
and I am trying to get it to be returned in 4 columns horizontally
21 22 23 24
25 26 27 28
29 30 39 39
44 42 40 43
...
as well as vertically
21 39 75 147
22 39 73 141
23 44 86 170
24 42 78 150
25 40 70 130
26 43 77 145
27 47 87 167
28 45 79 147
29 57 113 225
30 52 96 184
This is my attempt at solving this horizontally:
# prints array in columns
def printArray(array):
row = 10
col = 4
for i in range(row):
for j in range(col):
print(array[i][j], '\t', end="")
But it does not work.
I've also tried searching how to transpose the list some how but only found how to transpose a list of lists.
Transpose list of lists
Any help would be appreciated thank you.
For the horizontal you can use np.reshape:
np.array(list).reshape(-1, 4)
and for the vertical you can transpose:
np.array(list).reshape(4, -1).T
You can do with range
Vertical
col = 4
vertical = [lst[i:i+col] for i in range(0,len(lst),col)]
for item in vertical:
print(item)
Output:
[21, 22, 23, 24]
[25, 26, 27, 28]
[29, 30, 39, 39]
[44, 42, 40, 43]
[47, 45, 57, 52]
[75, 73, 86, 78]
[70, 77, 87, 79]
[113, 96, 147, 141]
[170, 150, 130, 145]
[167, 147, 225, 184]
Horizontal
row = 10
for s in range(row):
print([lst[s:][i] for i in range(0,len(lst),row)])
Output:
[21, 39, 75, 147]
[22, 39, 73, 141]
[23, 44, 86, 170]
[24, 42, 78, 150]
[25, 40, 70, 130]
[26, 43, 77, 145]
[27, 47, 87, 167]
[28, 45, 79, 147]
[29, 57, 113, 225]
[30, 52, 96, 184]
Together into a function.
def printarray(row, col):
print('----Vertical print----')
vertical = [lst[i:i+col] for i in range(0,len(lst),col)]
for item in vertical:
print(item)
print('\n')
print('----Horizontal print----')
for s in range(row):
print([lst[s:][i] for i in range(0,len(lst),row)])
Here are 2 functions that print both directions.
Horizontal output:
21 22 23 24
25 26 27 28
29 30 39 39
44 42 40 43
47 45 57 52
75 73 86 78
70 77 87 79
113 96 147 141
170 150 130 145
167 147 225 184
Vertical output:
21 39 75 147
22 39 73 141
23 44 86 170
24 42 78 150
25 40 70 130
26 43 77 145
27 47 87 167
28 45 79 147
29 57 113 225
30 52 96 184
Code:
data = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 39, 44, 42, 40, 43, 47, 45, 57, 52, 75, 73, 86, 78, 70, 77, 87, 79, 113, 96, 147, 141, 170, 150, 130, 145, 167, 147, 225, 184]
def print_horizontaly(lst: list, columns, spacing):
for i, item in enumerate(lst):
if i % columns == 0:
print("")
print(item, end=''.join(' ' for j in range(spacing - len(str(item)))))
def print_verticaly(lst: list, columns, spacing):
columns_ = []
for i in range(len(lst)//columns):
for item in lst[i::len(lst)//columns]:
print(item, end=''.join(' ' for j in range(spacing - len(str(item)))))
print("")
print_horizontaly(data, 4, 8)
print_verticaly(data, 4, 8)
How about this ?
list = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 39, 44, 42, 40, 43, 47, 45, 57, 52, 75, 73, 86, 78, 70, 77, 87, 79, 113, 96, 147, 141, 170, 150, 130, 145, 167, 147, 225, 184]
x = np.array(list) # Change list to 1D numpy matrix
x = x.reshape(int(len(x)/4), 4) # Reshape the matrix according to our requirement
If you use numpy library, it is very easy to reshape the list.
For making vertically reshaped array, you just make the array as 4 rows and 10 columns first, then transpose the array using numpy function.
import numpy as np
target_list = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 39, 44, 42, 40, 43, 47, 45, 57, 52, 75, 73, 86, 78, 70, 77, 87, 79, 113, 96, 147, 141, 170, 150, 130, 145, 167, 147, 225, 184]
# for horizontally
h_array = np.array(target_list).reshape((10, 4))
print(h_array)
# for vertically
v_array = np.array(target_list).reshape((4, 10))
print(v_array.T)
If you want to make the array as list of list, then you can you tolist function.
h_list = h_array.tolist()
print(h_list)
v_list = v_array.T.tolist()
print(v_list)
Try doing it this way:
def printArray(array):
row = 10
col = 4
#Horizontally
print("Horizontally:\n")
for i in range(0,len(array)-col,col):
for j in range(i,i+col):
print(array[j], '\t', end="")
print()
print()
print("Vertically:\n")
#Vertically
for i in range(0,row):
for j in range(i,i+10*4,row):
print(array[j], '\t', end="")
print()
lst = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 39, 44, 42, 40, 43, 47, 45, 57, 52, 75, 73, 86, 78, 70, 77, 87, 79, 113, 96, 147, 141, 170, 150, 130, 145, 167, 147, 225, 184]
printArray(lst)
Output:
Horizontally:
21 22 23 24
25 26 27 28
29 30 39 39
44 42 40 43
47 45 57 52
75 73 86 78
70 77 87 79
113 96 147 141
170 150 130 145
Vertically:
21 39 75 147
22 39 73 141
23 44 86 170
24 42 78 150
25 40 70 130
26 43 77 145
27 47 87 167
28 45 79 147
29 57 113 225
30 52 96 184

Stuck on Euler 18. My for loops aren't going up the rows

My code should compare the values on the bottom row and then add the highest out of each pair to the corresponding number above/adjacent to it. It works for the first row but doesn't iterate to get to the top.
Find the maximum total from top to bottom of the triangle below:
numbers = [
[75],
[95, 64],
[17, 47, 82],
[18, 35, 87, 10],
[20, 4, 82, 47, 65],
[19, 1, 23, 75, 3, 34],
[88, 2, 77, 73, 7, 63, 67],
[99, 65, 4, 28, 6, 16, 70, 92],
[41, 41, 26, 56, 83, 40, 80, 70, 33],
[41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
[63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
[4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]]
row = 14
col = 0
for j in range(14):
for i in range(len(numbers[row-1])):
if numbers[row][col] > numbers[row][col+1]:
numbers[row-1][col] += numbers[row][col]
col += 1
elif numbers[row][col] == numbers[row][col+1]:
numbers[row-1][col] += numbers[row][col]
col += 1
else:
numbers[row - 1][col] += numbers[row][col+1]
col += 1
row -= 1
col = 0
Here you go:
def get_max_sum(triangle, row_index):
if row_index == len(triangle):
return max(triangle[row_index - 1])
row = triangle[row_index]
previous_row = triangle[row_index - 1]
row[0] += previous_row[0]
for i in range(1, len(previous_row)):
row[i] += max(previous_row[i], previous_row[i - 1])
row[-1] += previous_row[-1]
triangle[row_index] = row
return get_max_sum(triangle, row_index + 1)
max_sum = get_max_sum(numbers, 1)
print(f'Max sum = {max_sum}')
Here is my solution based on the same logic used by you.
tri = """
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
"""
tri = tri.split("\n")[1:-1]
tri = [list(map(int, ele.split())) for ele in tri]
for row in range(len(tri)-2, -1, -1):
for ind, ele in enumerate(tri[row]):
if tri[row+1][ind] > tri[row+1][ind+1]:
tri[row][ind] += tri[row+1][ind]
else:
tri[row][ind] += tri[row+1][ind+1]
tri.pop()
print("Max sum:", tri[0][0])

Regarding ndarray creation in julia: Stacking in extra dimension

I would like to convert the following python code into julia:
import numpy as np
x = np.random.random([4,5,6])
y = np.array([[x, x, x ],
[2*x,3*x,4*x]])
print(y.shape)
-> (2, 3, 4, 5, 6)
In julia, the analogous syntax seems to me is
x = rand(4,5,6)
y = [x x x; 2x 3x 4x]
println(size(y))
-> (8, 15, 6)
These results are different. Can you tell me how to do it?
Using random numbers and multipliers obscures the details which you seek. Let's do consecutive numbering and try to get Python and Julia to display alike:
python>>>>>> z = np.reshape(np.array(range(1,121)), [4, 5, 6])
>>> z
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],
[ 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, 81, 82, 83, 84],
[ 85, 86, 87, 88, 89, 90]],
[[ 91, 92, 93, 94, 95, 96],
[ 97, 98, 99, 100, 101, 102],
[103, 104, 105, 106, 107, 108],
[109, 110, 111, 112, 113, 114],
[115, 116, 117, 118, 119, 120]]])
julia>z = reshape(1:120, 6, 5, 4)
6×5×4 reshape(::UnitRange{Int64}, 6, 5, 4) with eltype Int64:
[:, :, 1] =
1 7 13 19 25
2 8 14 20 26
3 9 15 21 27
4 10 16 22 28
5 11 17 23 29
6 12 18 24 30
[:, :, 2] =
31 37 43 49 55
32 38 44 50 56
33 39 45 51 57
34 40 46 52 58
35 41 47 53 59
36 42 48 54 60
[:, :, 3] =
61 67 73 79 85
62 68 74 80 86
63 69 75 81 87
64 70 76 82 88
65 71 77 83 89
66 72 78 84 90
[:, :, 4] =
91 97 103 109 115
92 98 104 110 116
93 99 105 111 117
94 100 106 112 118
95 101 107 113 119
96 102 108 114 120
So, if you want things to print similarly on the screen, you need to swap first and last dimension sizes (reverse the order of dimensions) on the arrays between Julia and Python. In addition, since Julia concatenates the arrays when you put them in the same brackets, but Python just nests its arrays in greater depth, you need to use np.reshape on Python or reshape on Julia to change the arrays to the shape you want. I suggest you check the resulting arrays on a consecutive set of integers to be sure they print alike before going back to your random floating point numbers. Remember that the indexing order is different when you access elements, too. Consider
>>> zzz = np.array([[z,z,z], [z,z,z]]) # python
> zzz = reshape([z z z; z z z], 6, 5, 4, 3, 2) # julia

removing all duplicates of max numbers in a correlation table

I need code for taking a .csv of a correlation table, sample of the table is posted here:
AA bb cc dd ff
AA 100 87 71 71 78
bb 87 100 73 74 81
cc 71 73 100 96 69
dd 71 74 96 100 71
ee 78 81 69 100 100
ff 72 73 68 68 71
Pg 68 69 62 62 64
Ph 68 69 69 62 64
Pi 68 69 62 62 64
Pj 68 69 63 63 64
Pk 70 71 65 65 67
I currently have read the .csv file with python's .csv module as a list of lists. I then removed the first column and row. And am now trying to take these int values and find the max values of each row. If there are multiple max values in a row, I want those values as well.
Then I intend to place that output into a table
file1values col row %
group1 AA AA 100
...
group1 dd ee 100
group1 ff ee 100
The issue I have so far is getting the max values for each row. Also I think I would be a bit confused on how to get the address (the col and row) for each max value.
Here is code so far:
from io import StringIO
import csv
import numpy as np
with open('/home/group1.csv', newline='') as csvfile:
reader = csv.reader(csvfile)
data_as_list = list(reader)
a = np.array(data_as_list)
a = np.delete(a, (0), axis=0)
a = np.delete(a, (0), axis=1)
np.set_printoptions(threshold=np.nan)
print (a)
print ('')
count = 0
b = (a.astype(int))
maxArr = []
while (count < b.shape[0]):
print (b[count])
count = count + 1
maxArr.append(max(b[count - 1]))
print (maxArr)
there are easier ways...
create a random matrix for tests
> import numpy as np
> m=np.random.randint(100,size=(10,10))
set diagonal to zero (or set to an out of range negative number)
> np.fill_diagonal(m,0)
array([[ 0, 35, 52, 40, 54, 1, 20, 41, 62, 92],
[45, 0, 75, 71, 85, 86, 83, 39, 52, 69],
[29, 21, 0, 78, 32, 14, 13, 27, 31, 26],
[99, 90, 16, 0, 28, 36, 30, 45, 85, 41],
[29, 21, 48, 31, 0, 86, 18, 7, 70, 76],
[96, 97, 34, 82, 51, 0, 69, 22, 27, 85],
[71, 58, 98, 42, 3, 51, 0, 19, 41, 93],
[54, 97, 86, 75, 62, 91, 78, 0, 55, 89],
[87, 44, 44, 54, 94, 94, 57, 24, 0, 81],
[94, 32, 1, 92, 34, 46, 96, 38, 75, 0]])
find the maximum values per column/row (since your matrix is symmetric doesn't matter)
> cm=np.argmax(m,1)
array([9, 5, 3, 0, 5, 1, 2, 1, 4, 6])
You will need to map the row/column indices to your labels.
> for r in range(10):
print(r,cm[r],m[r,cm[r]])
0 9 92
1 5 86
2 3 78
3 0 99
4 5 86
5 1 97
6 2 98
7 1 97
8 4 94
9 6 96

Categories

Resources