Extracting indices from numpy array python - python

I want the last 4 values of this equation.
Is there a better way to this in one step, like modifying the equation or another extraction technique other than using delete
a=5
d=2
n = np.cumsum(d ** np.arange(1, a+1))
print 'n=', n
n = np.delete(n,0)
print 'n extracted=', n
n= [ 2 6 14 30 62]
n extracted= [ 6 14 30 62]

print n[-4::]
will print the last 4 elements. You can do all kinds of array slicing like this, the above was just an example. You can index the array from the front or the back.

Related

How to take Different multi line inputs?

The other day, for the first time I participated in a coding contest and I faced an issue with taking inputs. There were 4 sample cases and each sample case had n test cases. So each sample case was in the format:
First line denotes number of test cases
Second line denotes number of elements in array A
Third line denotes elements of array A
Fourth line denotes elements of array B
To make more sense, the input was (say),
3 // Number of test cases
5 // Size of array A
2 4 3 7 9 // array A
14 21 11 // array B
3 // Size of array A
6 7 2 // array A
9 8 // array B
4 // Size of array A
5 2 6 7 // array A
12 17 // array B
The solution that I tried was
t = int(input()) # Number of sample cases
for i in t:
n = int(input()) # Size of array A
arr_A = [int(x) for x in input().split()]
arr_B = [int(x) for x in input().split()]
# Statements...
When I was running the code I was getting EOF error or some error. To test what was causing the error I reduced the aforementioned sample case to
1 // Number of test cases
5 // Size of array A
2 4 3 7 9 // array A
14 21 11 // array B
And with this input the code was running fine.
I will truly appreciate if you tell me possible ways of taking such inputs?
In your code, for i in t should be modified to for i in range(t) since we need to iterate up to a certain number.
This is the approach I usually use when it comes to taking inputs.
t = int(input())
while t > 0:
n = int(input())
arrA = list(map(int, input().split()))
arrB = list(map(int, input().split()))
t-=1

Sorting a random array using permutation

I tried to sort an array by permuting it with itself
(the array contain all the numbers in range between 0 to its length-1)
so to test it I used random.shuffle but it had some unexpected results
a = np.array(range(10))
random.shuffle(a)
a = a[a]
a = a[a]
print(a)
# not a sorted array
# [9 5 2 3 1 7 6 8 0 4]
a = np.array([2,1,4,7,6,5,0,3,8,9])
a = a[a]
a = a[a]
print(a)
# [0 1 2 3 4 5 6 7 8 9]
so for some reason the permutation when using the second example of an unsorted array returns the sorted array as expected but the shuffled array doesn't work the same way.
Does anyone know why? Or if there is an easier way to sort using permutation or something similar it would be great.
TL;DR
There is no reason to expect a = a[a] to sort the array. In most cases it won't. In case of a coincidence it might.
What is the operation c = b[a]? or Applying a permutation
When you use an array a obtained by shuffling range(n) as a mask for an array b of same size n, you are applying a permutation, in the mathematical sense, to the elements of b. For instance:
a = [2,0,1]
b = np.array(['Alice','Bob','Charlie'])
print(b[a])
# ['Charlie' 'Alice' 'Bob']
In this example, array a represents the permutation (2 0 1), which is a cycle of length 3. Since the length of the cycle is 3, if you apply it three times, you will end up where you started:
a = [2,0,1]
b = np.array(['Alice','Bob','Charlie'])
c = b
for i in range(3):
c = c[a]
print(c)
# ['Charlie' 'Alice' 'Bob']
# ['Bob' 'Charlie' 'Alice']
# ['Alice' 'Bob' 'Charlie']
Note that I used strings for the elements of b ton avoid confusing them with indices. Of course, I could have used numbers from range(n):
a = [2,0,1]
b = np.array([0,1,2])
c = b
for i in range(3):
c = c[a]
print(c)
# [2 0 1]
# [1 2 0]
# [0 1 2]
You might see an interesting, but unsurprising fact: The first line is equal to a; in other words, the first result of applying a to b is equal to a itself. This is because b was initialised to [0 1 2], which represent the identity permutation id; thus, the permutations that we find by repeatedly applying a to b are:
id == a^0
a
a^2
a^3 == id
Can we always go back where we started? or The rank of a permutation
It is a well-known result of algebra that if you apply the same permutation again and again, you will eventually end up on the identity permutation. In algebraic notations: for every permutation a, there exists an integer k such that a^k == id.
Can we guess the value of k?
The minimum value of k is called the rank of a permutation.
If a is a cycle, then the minimum possible k is the length of the cycle. In our previous example, a was a cycle of length 3, so it took three applications of a before we found the identity permutation again.
How about a cycle of length 2? A cycle of length 2 is just "swapping two elements". For instance, swapping elements 0 and 1:
a = [1,0,2]
b = np.array([0,1,2])
c = b
for i in range(2):
c = c[a]
print(c)
# [1 0 2]
# [0 1 2]
We swap 0 and 1, then we swap them back.
How about two disjoint cycles? Let's try a cycle of length 3 on the first three elements, simultaneously with swapping the last two elements:
a = [2,0,1,3,4,5,7,6]
b = np.array([0,1,2,3,4,5,6,7])
c = b
for i in range(6):
c = c[a]
print(c)
# [2 0 1 3 4 5 7 6]
# [1 2 0 3 4 5 6 7]
# [0 1 2 3 4 5 7 6]
# [2 0 1 3 4 5 6 7]
# [1 2 0 3 4 5 7 6]
# [0 1 2 3 4 5 6 7]
As you can see by carefully examining the intermediary results, there is a period of length 3 on the first three elements, and a period of length 2 on the last two elements. The overall period is the least common multiple of the two periods, which is 6.
What is k in general? A well-known theorem of algebra states: every permutation can be written as a product of disjoint cycles. The rank of a cycle is the length of the cycle. The rank of a product of disjoint cycles is the least common multiple of the ranks of cycles.
A coincidence in your code: sorting [2,1,4,7,6,5,0,3,8,9]
Let us go back to your python code.
a = np.array([2,1,4,7,6,5,0,3,8,9])
a = a[a]
a = a[a]
print(a)
# [0 1 2 3 4 5 6 7 8 9]
How many times did you apply permutation a? Note that because of the assignment a =, array a changed between the first and the second lines a = a[a]. Let us dissipate some confusion by using a different variable name for every different value. Your code is equivalent to:
a = np.array([2,1,4,7,6,5,0,3,8,9])
a2 = a[a]
a4 = a2[a2]
print(a4)
Or equivalently:
a = np.array([2,1,4,7,6,5,0,3,8,9])
a4 = (a[a])[a[a]]
This last line looks a little bit complicated. However, a cool result of algebra is that composition of permutations is associative. You already knew that addition and multiplication were associative: x+(y+z) == (x+y)+z and x(yz) == (xy)z. Well, it turns out that composition of permutations is associative as well! Using numpy's masks, this means that:
a[b[c]] == (a[b])[c]
Thus your python code is equivalent to:
a = np.array([2,1,4,7,6,5,0,3,8,9])
a4 = ((a[a])[a])[a]
print(a4)
Or without the unneeded parentheses:
a = np.array([2,1,4,7,6,5,0,3,8,9])
a4 = a[a][a][a]
print(a4)
Since a4 is the identity permutation, this tells us that the rank of a divides 4. Thus the rank of a is 1, 2 or 4. This tells us that a can be written as a product of swaps and length-4 cycles. The only permutation of rank 1 is the identity itself. Permutations of rank 2 are products of disjoint swaps, and we can see that this is not the case of a. Thus the rank of a must be exactly 4.
You can find the cycles by choosing an element, and following its orbit: what values is that element successively transformed into? Here we see that:
0 is transformed into 2; 2 is transformed into 4; 4 is transformed into 6; 6 is transformed into 0;
1 remains untouched;
3 becomes 7; 7 becomes 3;
5 is untouched; 8 and 9 are untouched.
Conclusion: Your numpy array represents the permutation (0 -> 2 -> 4 -> 6 -> 0)(3 <-> 7), and its rank is the least common multiple of 4 and 2, lcm(4,2) == 4.
it's took some time but I figure a way to do it.
numpy doesn't have this fiture but panda does have.
by using df.reindex I can sort a data frame by it indexes
import pandas as pd
import numpy as np
train_df = pd.DataFrame(range(10))
train_df = train_df.reindex(np.random.permutation(train_df.index))
print(train_df) # random dataframe contaning all values up to 9
train_df = train_df.reindex(range(10))
print(train_df) # sort data frame

How does the following code work for Matrix Multiplication in Python

I'm trying to do a matrix multiplication in python I have found the following code that I am trying to understand. (I know how to multiply matrices by hand and I want to understand how the following code performs the same action and by that i mean the first element in BA (row 1 column 1) is calculated by doing (1*1 + 3*3 + 3*3 + 1*1) etc.
from numpy import array
A= array([[ 1, 4, 5 ],[ 3, 2, 9], [ 3,6, 2], [ 1,6, 8]])
B=A.T
BA= array([[ 0, 0, 0 ],[ 0,0, 0], [ 0,0, 0] ])
for i in range(len(B)):
for j in range(len(A[0])):
for k in range(len(A)):
BA[i][j] += B[i][k] * A[k][j]
I know that the length command for a list returns how many elements there are in that list. I am not sure how it works here since B is a matrix, I assume it returns how many rows there are.
range of len(B) would be (0,3) corresponding to row 1,2 and 3.
for i in range would correspond to i=0, i=1, i= 2
next confusing thing is for j in range len(A[0])
The first element of A is the first row, the length here would thus correspond how many elements there are in the first element of A.
Basically I have a basic understanding of what range and len etc put out for this example but I would like to get a better understand of each value of i, j, k as a result of these as well as the last line which I really don't understand.
BA[i][j] += B[i][k] * A[k][j]
Please explain as basic as possible because I am new to programming and so at this point nothing is trivial to me. Thank you for your time to help others :)
Here is the actual result from your code:
B * A = AB
1 3 3 1 1 4 5 20 34 46
4 2 6 6 3 2 9 34 92 98
5 9 2 8 3 6 2 46 98 174
1 6 8
Assuming i = 0 and j = 0 lets calculate the BA[0][0], which is the first element from matrix BA.
BA[0][0] = B[0][k] * A[k][0]
B[0][k] means the line 0 from matrix B. As k is iterating over all lines of A, which is the same size as the number of columns in B.
A[k][0] means the column 0 from matrix A.
The loop for k in range(len(A)): will reproduce:
B[0][0]*A[0][0] + B[0][1]*A[1][0] + B[0][2]*A[2][0] + B[0][3]*A[3][0]
Resulting in:
1×1 + 3×3 + 3×3 + 1×1 = 20
Which is the value for BA[0][0] resulted from your code.
The following nested loops will iterate over all columns of A as j for every line of B as i in order to perform the multiplication for all (line) x (column) pairs:
for i in range(len(B)):
for j in range(len(A[0])):
Consider here the array as just a more convenient representation of the list you gave to the function.
A is built on top of the list [[ 1, 4, 5 ],[ 3, 2, 9], [ 3,6, 2], [ 1,6, 8]], a list of length 4.
range(start, stop) is a function which returns a generator which produces a sequence of integers, from the start to the stop point, stop not being included. If not provided, start defaults to 0.
B has a length of 4 rows so range(len(B)) will be like range(0, 3), which will produce 0,1 and 2 integers, when "asked" by the for loop. i will subsequently be 0,1 and 2.
A[0] returns the first row of A, which has a length of 3, so the same way, j will subsequently be 0, 1 and 2 (in this case) ; and k will subsequently be 0, 1, 2 and 3 as A has a length of 4.
BA[i] returns the row of index i. Which can also be indexed by j
So BA[i][j] is the element of row i and column j, which we increments by the product of the element of row i and index k of matrix B; and the element of row k and index j of matrix A.
In you code sample a matrix is represented a a list of sublists, where each sublist is a row.
So the most outer loop goes over the rows of B:
for i in range(len(B)):
A[0] is the first row of A, and the number of elements in it is the number of A's columns.
So the second loop goes over the columns of A:
for j in range(len(A[0])):
The most inner loop simply sums the products of the elements in the j-th row of B and the i-th row of A.
BA[i][j] += B[i][k] * A[k][j]
This add to BA[i][j] the product. += adds its right argument to its left one.

Sorting a 2 dimensional array after a part of an integer

I'm trying to sort a 2 dimensional Numpy array by the last entries, especially the last 2 characters of the integer. What I can already do is sort the array by the last number accordingly.
import numpy as np
a = np.array([[2,2,2,10006], [2,2,2,18015], [2,2,2,12002], [2,2,2,14005]])
print( a[a[:, 3].argsort()] )
The problem, however, is that the following comes out:
[[ 2 2 2 10006]
[ 2 2 2 12002]
[ 2 2 2 14005]
[ 2 2 2 18015]]
But what I would like to have is (02, 05, 06, 15 -> last 2 charakters of the integer):
[[ 2 2 2 12002]
[ 2 2 2 14005]
[ 2 2 2 10006]
[ 2 2 2 18015]]
And now comes the exciting part, the whole thing is done for a lot of entries and of course I want it to be super mega fast, so I think I should do it without the conversion to a string, the slicing and the sorting with an own algorithm. Somehow I have absolutely no idea about this very special question. Many thanks for the help!
import numpy as np
a = np.array([[7,8,9,10006],
[10,11,12,18015],
[1,2,3,12002],
[4,5,6,14005]])
# extract the absolute value of the number modulus 100
# to get the two trailing digits
print(np.mod(a[:, 3], 100))
# you could directly replace them in the array
a[:, 3] = np.mod(a[:, 3], 100)
print(a[a[:, 3].argsort()])

Read k matrices size nxm from stdin in Python

I need to read k matrices size nxm from stdin in Python.
In the first line there must be the number of matrices (k), and then - k descriptions of matrices: in the first line 2 integer numbers for size (n and m) devided by space, then the matrix.
Here's an example:
2
2 3
4 5 6
3 1 7
4 4
5 3 4 5
6 5 1 4
3 9 1 4
8 5 4 3
Could you please tell me how I can do this?
I could have done this only without considering m (for 1 matrix):
n = int(input())
a = []
for i in range(n):
a.append([int(j) for j in input().split()])
I have found some similar questions but stdin is not used (e.g. reading from file is used) or the size of string in matrix is not set.
You are on a right way. try to break it in simple steps. Basically a n X m matrix is n rows and each row would have m elements (pretty obvious). what if we have n=1 then we have a line in which there would be m element. to take such input we would just
matrix = input().split() #read the input
matrix = [ int(j) for j in matrix] #matrix is now 1 x m list
or simplify this
matrix = [ int(j) for j in input().split() ]
now suppose we have n rows, that means we have to do this n times which is simply looping n times ,
matrix = [ [ int(j) for j in input().split() ] for i in n ]
a more pythonic way is using map,
matrix= [ list( map(int, input().split() ) ) for i in range(n) ]

Categories