Selecting list values based on matrix binary values? - python

I am trying to map elements of a binary matrix to a list of integers. It needs to loop over each row of the matrix, if the value is 1 an item from the corresponding list is chosen and if the value is 0 no item is chosen. The end goal is to have a vector containing the sum of each row of corresponding values.
For example:
listOfNums: [1,2,3,4,5]
m1= [[1,0,1,1,1]
[0,0,0,0,1]
[1,0,0,0,1]]
>>>[13,5,6]
Here is what I have tried so far however I keep getting index errors
def corrspondingVal(self, x):
nums = [1,2,3,4,5,6,7,8,9,10]
return [self.nums[i] for i in range(x) if x[i]]
def sumPerRow(self):
v = np.apply_along_axis(self.correspondingVals(self.matrix1), axis=1, arr=self.matrix1)
return v
(self.matrix1 is a (10,5) matrix of binary values)

Here is one short way, although the multiplication may be expensive.
np.sum(m1 * list, axis=1)
Even better is
np.dot(m1, list)

Without numpy:
listOfSums = [ sum(num for idx,num in enumerate(listOfNums) if row[idx]) for row in m1 ]

Related

How can I use a for-loop to examine a two-dimensional array from a two-dimensional array?

What I want is to repeat the 10x10 array by 3x3 array. For example, an array of 3x3 contains nine values of indexes [0][0:3], [1][0:3], [2][0:3], and I want to find the max value of these nine values and apply them to a new array. I will add a picture and what I tried.
enter image description here
[1
array_33 = []
new_list = []
for i in range(10):
for j in range(10):
array_33.append([i:i+3])
max_value = max(map(max, array_33) # to find a max_vlaue in 3x3 array
new_list.append(max_value)
One row succeeded in finding a value up to index [0:3], but the next row failed to find a way to get a value up to [0:3]. The value [8:10] is not divided by 3, so the value is added to the new array as it is. Then I want to do a repetitive task of finding a value of [0:3] from lines 4 to 6. I dont know how can i do this
you can use 2D slicing from numpy:
import numpy as np
a = np.array([[(i+1)%10 for i in range(10)]]*10)
print(a)
sz = 3
b = [[np.max(a[i:i+3, j:j+3])
for j in range(0,a.shape[1],sz)]
for i in range(0,a.shape[0],sz)]
print(b)
generally, a[row1:row2, col1:col2] will give you the submatrix in those indexes (not including the last index)

How to count an element that exceed our criteria in a list that is in a list that is also in a list (a list with a depth of 4 lists (?))?

I'm trying to count how many element that is exceed some criteria (for exemple: 0.7) and then convert them into percent, the element is in a multiple list that look like this:
[[[[0.00173012]
[0.0009075 ]
[0.00080378]
...
[0.00069336]
[0.00074539]
[0.00186453]]
[[0.00081442]
[0.00022855]
[0.00019197]
...
[0.00018318]
[0.00017222]
[0.00075811]]
[[0.00084458]
[0.00020444]
[0.0001783 ]
...
[0.00020849]
[0.00017066]
[0.00070635]]
...
[[0.00073932]
[0.00022051]
[0.00024553]
...
[0.00028661]
[0.00019603]
[0.0007242 ]]
[[0.00085666]
[0.0002345 ]
[0.00021651]
...
[0.0002319 ]
[0.00017067]
[0.00066847]]
[[0.00188439]
[0.00092146]
[0.00082662]
...
[0.00077084]
[0.00066442]
[0.00178707]]]]
info: there is ... because it is a long list and cant fit all the list in the output cell (it is originally an image)
I've tried using:
len(pex > 0.7)/100
#pex is variable contain the multiple list above
but it's not really working because the ouput from the len is just 1, and if i divide it by 100 the output will be just 0.01
Is there any way for me to easily count all the element and the element that exceed some criteria so i can convert them into percent?? TIA
If you are allowed to use numpy this can be easily done, consider following example
import numpy as np
data = [[[1,2],[3,4]],[[5,6],[7,8]]]
arr = np.array(data) # create numpy.array
print(np.sum(arr>5)) # count elements > 5
print(arr.size) # number of all elements
output
3
8
Explanation: convert nested lists into numpy.array use comparison to get same-shaped array with Trues where value greater than 5 and Falses elsewhere, then use numpy.sum (not built-in sum function) to get count, as True and False are treated as 1 and 0 when subjected to arithmetic operations (this also apply outside numpy, e.g. sum([True,True,True]) gives 3)
I'm not sure of why this data structure was choosen but it look simpler to me to just flatten the list and sub list in a single list with all elements then perform operations on it :
def flatten(l):
res = []
for el in l:
if type(el) == list:
#If it's a list then we extract all the elements in it
res.extend(flatten(el))
else:
#Only add in the result the non-list elements
res.append(el)
return res
dex = [[[[0.00173012],
[0.0009075 ],
[0.00080378],
[0.00069336],
....
[0.00074539],
[0.00186453]]]]
flatten_dex = flatten(dex)
#Here flatten_dex is [0.00173012, 0.0009075, 0.00080378, 0.00069336, ..., 0.00074539, 0.00186453]
Once you have this list it's much simple to count the number of elements matching the condition :
nb_elements_greater_than_0_8 = len([e for e in flatten_dex if e > 0.8])
number_of_total_elements = len(flatten_dex)

Python: Finding all 6x6 matrices where each value occurs only once in each column and row

I want to generate all 6x6 matrices in Python where each value (integer 1-6) occurs only once in each column and row (like a sudoku puzzle, except for the subgrids). Generating all possible 6x6 matrices and filtering afterwards is not an option I believe as there are ~1.3*10^17 possibilities.
I found that when picking a permutation of the sequence 1-6 (720 in total), the 2nd row for the matrix will only have 265 possibilities, with 3rd-4th-5th row having even less. 6th row should have only 1 possibility if the previous 5 rows have been picked.
I have tried the code below for a 3x3 matrix and it works, however I feel adding more nested loops with more comparisons is not the best way (if a way at all) to tackle this issue. It sounds like it should be doable with a recursion or list comprehension but I can't lay my finger on it.
import itertools
input_list = []
for f in itertools.permutations([1,2,3],3):
input_list.append(f)
for i in input_list:
input_listcopy = input_list.copy()
result = []
result.append(i)
input_listcopy.remove(i)
for j in input_listcopy:
if (i[0] != j[0] and i[1] != j[1] and i[2] != j[2]):
result.append(j)
print(result)
Just to be clear, the output I expect is a 2D list where each element is one row of the matrix, starting from the top:
[[1,2,3],[2,3,1],[3,1,2]]
Thanks in advance!
What about this?
from itertools import permutations
# Define the permutations
length = 6
elements = range(1, length+1)
result = []
for perm in permutations(elements, length):
if not result: # The first permutation is added
result.append(perm)
continue
is_valid_list = []
for row in result:
is_valid = all(perm[idx] != row[idx] for idx in range(length))
is_valid_list.append(is_valid)
if all(is_valid_list):
result.append(perm)
print(result)

Excluding values in array - python

Ok so I have an array in python. This array holds indices to another array. I removed the indices I wanted to keep from this array.
stations = [1,2,3]
Let's call x the main array. It has 5 columns and I removed the 1st and 5th and put the rest in the array called stations.
I want to be able to create an if statement where the values from stations are excluded. So I'm just trying to find the number of instances (days) where the indices in the stations array are 0 and the other indices (0 and 4) are not 0.
How do I go about doing that? I have this so far, but it doesn't seem to be correct.
for j in range(len(x)):
if x[j,0] != 0 and x[j,4] != 0 and numpy.where(x[j,stations[0]:stations[len(stations)-1]]) == 0:
days += 1
return days
I don't think your problem statement is very clear, but if you want the x cols such that you exclude the indices contained in stations then do this.
excluded_station_x = [col for i, col in enumerate(x) if i not in stations]
This is a list comprehension, its a way for building a new list via transversing an iterable. Its the same as writing
excluded_station_x = []
for i, col in enumerate(x):
if i not in stations:
excluded_station_x.append(col)
enumerate() yields both the value and index of each element as we iterate through the list.
As requested, I will do it without enumerate.
You could also just del each of the bad indices, although I dislike this because it mutates the original list.
for i in stations:
del x[i]

How to pick the largest number in a matrix of lists in python?

I have a list-of-list-of-lists, where the first two act as a "matrix", where I can access the third list as
list3 = m[x][y]
and the third list contains a mix of strings and numbers, but each list has the same size & structure. Let's call a specific entry in this list The Number of Interest. This number always has the same index in this list!
What's the fastest way to get the 'coordinates' (x,y) for the list that has the largest Number of Interest in Python?
Thank you!
(So really, I'm trying to pick the largest number in m[x][y][k] where k is fixed, for all x & y, and 'know' what its address is)
max((cell[k], x, y)
for (y, row) in enumerate(m)
for (x, cell) in enumerate(row))[1:]
Also, you can assign the result directly to a couple of variables:
(_, x, y) = max((cell[k], x, y)
for (y, row) in enumerate(m)
for (x, cell) in enumerate(row))
This is O(n2), btw.
import itertools
indexes = itertools.product( xrange(len(m)), xrange(len(m[0]))
print max(indexes, key = lambda x: m[x[0]][x[1]][k])
or using numpy
import numpy
data = numpy.array(m)
print numpy.argmax(m[:,:,k])
In you are interested in speeding up operations in python, you really need to look at numpy.
Assuming "The Number of Interest" is in a known spot in the list, and there will be a nonzero maximum,
maxCoords = [-1, -1]
maxNumOfInterest = -1
rowIndex = 0
for row in m:
colIndex = 0
for entry in row:
if entry[indexOfNum] > maxNumOfInterest:
maxNumOfInterest = entry[indexOfNum]
maxCoords = [rowIndex,colIndex]
colIndex += 1
rowIndex += 1
Is a naive method that will be O(n2) on the size of the matrix. Since you have to check every element, this is the fastest solution possible.
#Marcelo's method is more succulent, but perhaps less readable.

Categories