How to compare specific elements in 2D array in Python - python

I'm trying to compare these specific elements to find the highest number:
Q_2 = [[5,0,41],[6,3,5],[7,4,3],[8,5,40]]
This is my 2d array in Python I want to compare Q_2[i][2] with each other the example is that number 41 gets compared to 5 and 3 and 40 and the result is the highest number.
I came up with 2 ways:
I store the Q_2[i][2] of the every item to a new list (which I don't know why it wont)
Or I do a loop to compare them
from array import *
#These 2 are used to define columns and rows in for other 2d arrays (All arrays have same column and row)
n = int(3)
m = int(input("Enter number of processes \n")) #I always type 4 for this variable
Q_2 = [[5,0,41],[6,3,5],[7,4,3],[8,5,40]]
for i in range(m):
for j in range(1,3,1):
if(Q_2[i][2]>=Q_2[j][2]:
Max_Timers = Q_2[i]
print(Max_Timers) #to check if the true value is returned or not
The result it returns is 40
This worked when the 0 index was lower then others but once I changed the first one to 41 it no longer works

there is no need of two 'for' loops, as your are after just one element from a 2D array rather than complete 1D array.
This is a working code on 2D array, to get the 1D array that got the highest element on index-2:
max_index = 0
Q_2 = [[5,0,41],[6,3,5],[7,4,3],[8,5,40]]
for i in range(len(Q_2)):
if(Q_2[i][2]>=Q_2[max_index][2]):
max_index = i
print(Q_2[max_index])

The reason your code doesn't work can be easily found out by working out a dry run using the values you are using.
According to your logic,
number 41 gets compared to 5 and 3 and 40 and the result is the highest number
and this is achieved by the two for loops with i and j. But what you overlooked was that the max-value that you calculated was just between the current values and so, you are saving the max value for the current iteration only. So, instead of the Global maximum, only the local/current maximum was being stored.
A quick dry-run of your code (I modified a few lines for the dry-run but with no change in logic) will work like this:
41 is compared to 5 (Max_Timers = 41)
41 is compared to 3 (Max_Timers = 41)
5 is compared to 3 (Max_Timers = 5)
40 is compared to 5 (Max_Timers = 40)
40 is compared to 3 (Max_Timers = 40)
>>> print(Max_timers)
40
So, this is the reason you are getting 40 as a result.
The solution to this is perfectly mentioned by #Rajani B's post, which depicts a global comparison by storing the max value and using that itself for comparison.
Note: I didn't mention this above but even when you used a 2nd for loop, which was already not required, there was an even less reason for you to use a range(1,3,1) in the 2nd loop. As you can see in the dry-run, this resulted in skipping a few of the checks that you probably intended.

You can use numpy to significantly simplify this task and for performance as well. Convert your list into an np.array(), then select the column of interest, which is Q_2[:,2] and apply numpy's .max() method.
import numpy as np
Q_2 = [[5,0,41],[6,3,5],[7,4,3],[8,5,40]]
Q_2 = np.array(Q_2)
mx2 = Q_2[:,2].max()
which gives the desired output:
print(mx2)
41

Related

Add to a array using a formula based on the last entry in an array n number of times

I'm attempting to build an array from a known starting value that appends to itself based on a formula that includes the last number of the list. I'd like to do this a specified number of times. So for example:
List starts at 5
The formula I use = last number in a list X 2
The new entry to the list is 10
The next new entry is 20
My non-working code is below:
mean = 198
standard_deviation = 85
list = [((mean)-(standard_deviation*3))]
list.append(((list[-1])+(standard_deviation*.1)))
print(list)
[-55.930192782739596, -47.4592697321513]
I'd like to be able to tell the array to stop after 30 entries.
list = [((mean)-(std*3))]
for n in range(60):
list.append(((list[-1])+(std*.1)))

Random partitioning given array with given bin sizes

How to randomly partition given array with given bin sizes?
Is there an inbuilt function for that? For example, I want something like
function(12,(2,3,3,2,2)) to output four partitions of numbers from 1 go 12 (or 0 to 11, doesn't matter). So output may be a list like [[3,4],[7,8,11],[12,1,2],[5,9],[6,10]](or some other efficient data structure). The first argument of the function may be just a number n, in which case it will consider np.arange(n) as the input, otherwise it may be any other ndarray.
Of course we can randomly permute the list and then pick the first 2, next 3, next 3, next 2 and last 2 elements. But does there exist something more efficient?
numpy.partition() function has a different meaning, it performs a step in quicksort, and I also couldn't find any such function in the numpy.random submodule.
Try this following solution:
def func(a, b:List):
# a is integer and b is a python list
indx = np.random.rand(a).argsort() # Get randomly arranged index
b = np.array(b)
return np.r_[np.split(indx,b.cumsum()[:-1])] # split the index and merge

Fredo and Array Update in python

I will have an interview with a company which like the hackerearth.com. I don't know how to work and doing the code perfectly. Could you help me with the following example?
This is the example for the .hackerearth.com, however, I don't know that I should consider the constraint in the code? can I use a package like NumPy? or I should only use the basic calculation with my self? Could you check my response and let me know the problem with that? Thank you so much
Input Format:
First line of input consists of an integer N denoting the number of elements in the array A.
Second line consists of N space separated integers denoting the array elements.
Output Format:
The only line of output consists of the value of x.
Input Constraints:
1<N<100
1<A[i]<100
explanation:
An initial sum of array is 1+2+3+4+5=15
When we update all elements to 4, the sum of array which is greater than 15 .
Note that if we had updated the array elements to 3, which is not greater than 15 . So, 4 is the minimum value to which array elements need to be updated.
# Write your code here
import numpy as np
A= [1, 2, 3,4,5]
for i in range(1, max(A)+1):
old = sum(A)
new = sum(i*np.ones(len(A)))
diff = new-old
if diff>0:
print(i)
break
Well this isn't Code Review stack exchange, but:
You don't say how to calculate x. It seems to be something to do with finding an average value, but no-one can judge your code without know what it's trying to do. A web search suggests it is this:
Fredo is assigned a new task today. He is given an array A containing N integers. His task is to update all elements of array to some minimum value x , that is, ; such that sum of this new array is strictly greater than the sum of the initial array. Note that x should be as minimum as possible such that sum of the new array is greater than the sum of the initial array.
Given that the task starts by accepting input, it's important that your program does this part.
N = int(input()) # you can put a prompt string in here, but may conflict with limited output
A = list(map(int,input().split()))
# might need input checks
# might need range checks
# might check that A has exactly N values
you don't need to recalculate old = sum(A) every time around your search loop
calculation of new doesn't need a sum at all - it's just new = i * len(A)
there's no point in checking values of i at or below min(A)
your search will fail if all values of A are the same (try it), because you never look above max(A)
These remarks apply to your approach; a more efficient search would be binary chop, and there is also a mathematical way to go straight to the answer from sum(A) without any searching:
x = sum(A) // len(A) + 1
You don't need numpy or looping for this. Get the average of the array elements, then get the next higher integer from this.
N = 5
A = [1, 2, 3, 4, 5]
total = sum(A)
avg = A/N # not checking for zero-divide because conditions say N > 1
x = floor(avg + 1)
print(x)
Adding 1 is necessary to make the new sum greater than the original sum when the average is an exact integer (e.g. 15/5 == 3).

Randomly select a length of numbers from numpy array

I have a number of data files, each containing a large amount of data points.
After loading the file with numpy, I get a numpy array:
f=np.loadtxt("...-1.txt")
How do I randomly select a length of x, but the order of numbers should not be changed?
For example:
f = [1,5,3,7,4,8]
if I wanted to select a random length of 3 data points, the output should be:
1,5,3, or
3,7,4, or
5,3,7, etc.
Pure logic will get you there.
For a list f and a max length x, the valid starting points of your random slices are limited to 0, len(f)-x:
0 1 2 3
f = [1,5,3,7,4,8]
So all valid starting point can be selected with random.randrange(len(f)-x+1) (where the +1 is because randrange works like range).
Store the random starting point into a variable start and slice your array with [start:start+x], or be creative and use another slice after the first:
result = f[random.randrange(len(f)-x+1):][:3]
Building on usr2564301's answer you can take out only the elements you need in 1 go using a range so you avoid building a potentially very large intermediate array:
result = f[range(random.randrange(len(f)-x+1), x)]
A range also avoids that you build large index arrays when your length x becomes larger.

Sum of array diagonal

I'm very new at this and have to do this for a project so keep that in mind.
I need to write a function sumOfDiagonal that has one parameter of type list.
The list is a 4x4 2-dimensional array of integers (4 rows and 4 columns of integers).
The function must return the sum of the integers in the diagonal positions from top right to bottom left.
I have not tried anything because I have no idea where to begin, so would appreciate some guidance.
Since you haven't specified a language (and this is probably classwork anyway), I'll have to provide pseudo-code. Given the 4x4 2d array, the basic idea is to use a loop specifying the index, and use that index to get the correct elements in both dimensions. Say we had the array:
[][0] [][1] [][2] [][3]
----- ----- ----- -----
[0][] 1 2 3 4
[1][] 5 6 7 8
[2][] 9 10 11 12
[3][] 13 14 15 16
and we wanted to sum the top-left-to-bottom-right diagonal (1+6+11+16)(1). That would be something like:
def sumOfDiagonal (arr, sz):
sum = 0
for i = 0 to sz - 1 inclusive:
sum = sum + arr[i][i]
return sum
That's using the normal means of accessing an array. If, as may be given the ambiguity in the question, your array is actually a list of some description (such as a linked list of sixteen elements), you'll just need to adjust how you get the "array" elements.
For example, a 16-element list would need to get nodes 0, 5, 10 and 15 so you could run through the list skipping four nodes after each accumulation.
By way of example, here's some Python code(2) for doing the top-left-to-bottom-right variant, which outputs 34 (1+6+11+16) as expected:
def sumOfDiagonals(arr):
sum = 0
for i in range(len(arr)):
sum += arr[i][i]
return sum
print(sumOfDiagonals([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]))
(1) To do top right to bottom left simply requires you to change the second term into sz - i - 1.
(2) Python is the ideal pseudo-code language when you want to be able to test your pseudo-code, provided you stay away from its more complex corners :-)

Categories

Resources