Why is this index function showing a 2 instead of a 4? - python

When I am running the following code, I get 0,1,2,3,2 to be printed out. Why would a 2 be printed as the last number when it should be a 4? The index function should be printing the index of each of the lists inside of the big list, correct? Using Python btw
game_board = [["o", 1, 0, 0, 0],
[2, 2, 0, 0, 0],
[0, 0, 2, 2, 2],
[0, 0, 2, "o", 2],
[0, 0, 2, 2, 2]]
for i in game_board:
print(game_board.index(i))

using the index function of a list returns the first occurrence of an item. Here's a simplified example:
game_board = [0,2,5,2,3]
game_board.index(2)
>>> 1
This returns the first time the number two is seen in your list.
In your example, the row
[0, 0, 2, 2, 2]
is at index 2 and index 4. When iterating over each list and looking for it's index, rows 0, 1, 2, and 3 return correctly but because the row at index 4 is the same at index 2, it will return the number 2.

Related

Accessing neighbour indices in a particular element of an array (python)

I have a two dimensional list like :
data = [[0,0,0,0,0,1,0,0,0,0], [0,1,0,0,0,0,0,0,0,0]]
How can I access the index of the neighbours, where the value equals 1?
Expected output:
[[4, 5, 6], [0, 1, 2]]
For example, the indices of an array data in first row at value 1 is 5, so I need to access its left and right side neighbour indices like 4 and 6. Same way for row 2.
If I understand description well (please clarify) , maybe you can try this one. Additionally, you can check edge case where there is no 1, or no left or right .
import numpy as np
a = np.array([
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]])
if __name__ == "__main__":
indices = np.where(a == 1)[1]
indices = indices.reshape(-1,1)
indices = np.concatenate([indices-1,indices,indices+1],-1)
print(indices)
One efficient solution is using FOR loops:
for i in range(2):
for j in range(10):
if a[i][j]==1:
print(str(i)+' '+str(j))
If using lists, here is a one approach which identifies the indexes of the neighbours of 1. As a caveat, this will fail with a index out of range, if the 1 value is the first of last element in the list.
Input:
data = [[0,0,0,0,0,1,0,0,0,0], [0,1,0,0,0,0,0,0,0,0]]
Example:
[[i-1, i, i+1] for sub in data for i, j in enumerate(sub) if j == 1]
Output:
[[4, 5, 6], [0, 1, 2]]

Mapping a list of elements to a range of an element from another list to create unique matrices

I am trying to "map a list of elements to a range of an element from another list to create unique matrices." Let me explain with a drawing.
Kickstart-inspired question
I hope that it makes sense.
This is inspired by Google Kickstart competition, which means that it is not a question exactly required by the contest.
But I thought of this question and I think that it is worth exploring.
But I am stuck with myself and not being able to move on much.
Here is the code I have, which obviously is not a correct solution.
values = input("please enter your input: ")
values = values.split()
values = [int(i) for i in values]
>>> please enter your input: 2 4 3 1 0 0 1 0 1 1 0 0 1 1 0 6 4 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0
rows_columns = []
matrix = []
for i in values:
if i > 1:
rows_columns[:1].append(i) # The "2" at the very beginning indicates how many matrices should be formed
elif i <= 1:
matrix.append(i)
rows_columns[:1]
>>> [4, 3, 6, 4]
matrix_all = []
for i in range(1, len(rows_columns)):
matrix_sub = []
for j in range(rows_columns[i]):
matrix_sub.append(matrix[j])
if matrix_sub not in matrix_all:
matrix_all.append(matrix_sub)
>>> [[1, 0, 0, 1], [1, 0, 0], [1, 0, 0, 1, 0, 1], [1, 0, 0, 1]]
I really wonder if the nested loop is a good idea to solve this question. This is the best way I could think of for the last couple of hours. What I want to get as a final result looks like below.
Final expected output
Given that there is information about how many rows and columns there should be on a matrix on one list and just enough numbers of elements to form the matrix on the other, what would be the solution to map(or create) the two matrices out of the other list, based on the dimensionality information on a list?
I hope that it is clear, let me know when it is not.
Thanks!
Without using numpy, here is one working solution, based on the input found in your code snippet, and the expected result listed in your final expected result link:
values = [2, 4, 3, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 6, 4, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
0, 1, 0, 1, 0, 1, 1, 1, 0]
v_idx = 1
"""
As per example, the number of matrices desired is found in the first input list element.
In the above values list, we want 2 matrices. The for loop below therefore executes exactly 2 times
"""
for matrix_nr in range(values[0]):
# The nr of rows and nr of columns are the next two elements in the values list
nr_rows = values[v_idx]
nr_cols = values[v_idx + 1]
# Calculate the start index for the next matrix specifications
new_idx = v_idx+2+(nr_rows*nr_cols)
# Slice the values list to extract the values for the current matrix to format
sub_elements = values[v_idx+2: new_idx]
matrix = []
# Append elements to the matrix by slicing values according to nr_rows and nr_cols
for r in range(nr_rows):
start_idx = r*nr_cols
end_idx = (r+1)*nr_cols
matrix.append(sub_elements[start_idx:end_idx])
print(matrix)
v_idx = new_idx
This gives the expected result:
[[1, 0, 0], [1, 0, 1], [1, 0, 0], [1, 1, 0]]
[[1, 0, 0, 0], [1, 0, 0, 1], [1, 1, 1, 1], [1, 0, 1, 0], [1, 0, 1, 0], [1, 1, 1, 0]]
As said, numpy could very likely be used to be a lot more efficient.

list.index() does not find existing element [duplicate]

This question already has answers here:
Don't understand why string.index("word") isn't working
(3 answers)
Closed 3 years ago.
I have a nested list of binary values (0,1) as integers.
I know we cannot recursively descend into a multidimensional list to find the element so i put a loop to get a single list.
And then calling list.index(0) it finds the correct index of 0's but when i call list.index(1) it returns a value error. I am mainly looking for an explanation not a solution.
Code:
def getA(a):
b = 0
m = []
for j in range(a):
b = b+j
for x in range(b+1):
m.append(getR(x))
for z in m:
print(z.index(1)) # Throws ValueError: 1 is not in list
However printing z:
[0, 0, 0, 0, 0]
[0, 0, 0, 1, 1]
[0, 0, 1, 0, 1]
[0, 0, 1, 1, 0]
[0, 1, 0, 0, 1]
[0, 1, 0, 1, 0]
[0, 1, 1, 0, 0]
[1, 0, 0, 0, 1]
[1, 0, 0, 1, 0]
[1, 0, 1, 0, 0]
[1, 1, 0, 0, 0]
and finally printing z.index(0):
0
0
0
0
0
0
0
1
1
1
2
list.index(1) returns a value error because your first list ([0, 0, 0, 0, 0]) does not have a '1' in it. You'd see a similar response if you tried list.index(2)
This is how the method index works. If it does not find value in the list it raises exception Value Error.
Since each list contains 0 it works fine and returns the first index for 0 in each list.
But for example, the first list does not contain 1 and that is why it raises an exception.
You can add 1 to the first list and see that exception is no longer raised.

How maintain sequence of occurence of numbers from ndarray into set using python?

The Scenario
I'm trying to get the number of clusters a dataframe belongs to.
Whose Data type is <type 'numpy.ndarray'> and data as below
records_Array = array([0, 0, 0, 0, 2, 2, 1, 1, 1], dtype=int32)
Obviously while printing I see [0 0 0 ..., 1 1 1] in this format.
Now, I need the numbers only once, so I convert into set and then to List,
cluster_set = list(set(records_Array))
The Output
On printing cluster_set, I get [0, 1, 2]
where as the clusters are in sequence of 0, 2, 1
Required
I need some function / method, that preserves the sequence of records_Array and returns in cluster_set
You want Pandas' pd.unique as it does not sort as it finds unique values. Numpy's unique function does.
a = np.array([0, 0, 0, 0, 2, 2, 1, 1, 1])
pd.unique(a)
array([0, 2, 1])

How can I find the second most common number in an array?

I have tried using scipy.stats mode to find the most common value. My matrix contains a lot of zeros, though, and so this is always the mode.
For example, if my matrix looks like the following:
array = np.array([[0, 0, 3, 2, 0, 0],
[5, 2, 1, 2, 6, 7],
[0, 0, 2, 4, 0, 0]])
I'd like to have the value of 2 returned.
Try collections.Counter:
import numpy as np
from collections import Counter
a = np.array(
[[0, 0, 3, 2, 0, 0],
[5, 2, 1, 2, 6, 7],
[0, 0, 2, 4, 0, 0]]
)
ctr = Counter(a.ravel())
second_most_common_value, its_frequency = ctr.most_common(2)[1]
As mentioned in some comments, you probably are speaking of numpy arrays.
In this case, it is rather simple to mask the value you want to avoid:
import numpy as np
from scipy.stats import mode
array = np.array([[0, 0, 3, 2, 0, 0],
[5, 2, 1, 2, 6, 7],
[0, 0, 2, 4, 0, 0]])
flat_non_zero = array[np.nonzero(array)]
mode(flat_non_zero)
Which returns (array([2]), array([ 4.])) meaning the value appearing the most is 2, and it appears 4 times (see the doc for more info). So if you want to only get 2, you just need to get the first index of the return value of the mode : mode(flat_non_zero)[0][0]
EDIT: if you want to filter another specific value x from array instead of zero, you can use array[array != x]
original_list = [1, 2, 3, 1, 2, 5, 6, 7, 8] #original list
noDuplicates = list(set(t)) #creates a list of all the unique numbers of the original list
most_common = [noDuplicates[0], original_list.count(noDuplicates[0])] #initializes most_most common to
#the first value and count so we have something to start with
for number in noDuplicates: #loops through the unique numbers
if number != 0: #makes sure that we do not check 0
count = original_list.count(number) #checks how many times that unique number appears in the original list
if count > most_common[1] #if the count is greater than the most_common count
most_common = [number, count] #resets most_common to the current number and count
print(str(most_common[0]) + " is listed " + str(most_common[1]) + "times!")
This loops through your list and finds the most used number and prints it with the number of occurrences in your original list.

Categories

Resources