extract integer from an array in a certain interval - python

I would like to extract the number from an array at a certain interval. The array is of size (1,20). I want to print the number from this array at an interval of 4. I am trying to print all the 4th numbers from 0 to 20 from the array. But I suspect my code Is not printing the right 4th number in the range 0 to 20. I am trying to extract the column numbers from stimnumber here. stimnumber has a shape (1,20)
If
stimnuber = [[1,1,1,1,4,4,4,4,8,8,8,8,9,9,9,9,0,0,0,0]]
I want to print all the numbers 1, 4, 8, 9 and 0.
j = 0
for j in range(stimnumber.shape[1]):
while j < 5:
stimnum = stimnumber[:,j::20]
print(stimnum[:,j])
j += 20

Just iterate with a step of 4
stimnumber =[[1,1,1,1,4,4,4,4,8,8,8,8,9,9,9,9,0,0,0,0]]
for i in range(0,len(stimnumber[0]),4):
print(stimnumber[0][i])
Or as pointed by wjandrea if you are familiar with array slicing (https://www.geeksforgeeks.org/python-list-comprehension-and-slicing/) you can try:
stimnumber =[[1,1,1,1,4,4,4,4,8,8,8,8,9,9,9,9,0,0,0,0]]
for i in stimnumber[0][::4]: print(i)
basically it means [start, stop, step] for the array locations

Related

How to find the most frequent progressive digit from a list of 4-digits numbers

I am quite new in Python programming. What's an efficient and Pyhtonic way to find the most frequent progressive digit from a list of 4-digits numbers?
Let's say I have the following list: [6111, 7111, 6112, 6121, 6115, 6123].
The logic is to observe that the for the first digit the 6 is the most frequent. I can eliminate the number 7111 for the next considerations.
For the second digit I consider the new candidates [6111, 6112, 6121, 6115, 6123] and I observe that the 1 is the most frequent digit and so on.
At the end of the algorithm I'll have just 1 number of the list left.
If there are 2 or more number with the same occurrences for a digit I can either pick the smaller one on a random one between all of them.
A simple approach could be to convert the list into a Nx4 matrix and consider for each column the most frequent digit. This could work but I find a very stupid and inefficient way to solve this problem. Can anyone help?
EDIT: my code for this solution (NOTE: THIS CODE DOES NOT ALWAYS WORK, SOMETHING IS WRONG. FOR THE SOLUTION TO THIS PROBLEM PLEASE REFER TO #MadPhysicist ANSWER)
import numpy as np
import pandas as pd
from collections import Counter
numbers_list = [6111, 7111, 6112, 6121, 6115, 6123]
my_list = []
for number in numbers_list:
digit_list = []
for c in str(number):
digit_list.append(c)
my_list.append(digit_list)
matrix = np.array(my_list)
matrix0 = matrix
my_counter = Counter(matrix.T[0]).most_common(1)
i=0
for digit0 in matrix.T[0]:
if digit0 != my_counter[0][0]:
matrix0 = np.delete(matrix, i, 0)
i += 1
matrix = matrix0
matrix1 = matrix
my_counter = Counter(matrix.T[1]).most_common(1)
i=0
for digit1 in matrix.T[1]:
if digit1 != my_counter[0][0]:
matrix1 = np.delete(matrix, i, 0)
i += 1
matrix = matrix1
matrix2 = matrix
my_counter = Counter(matrix.T[2]).most_common(1)
i=0
for digit2 in matrix.T[2]:
if digit2 != my_counter[0][0]:
matrix2 = np.delete(matrix, i, 0)
i += 1
matrix = matrix2
matrix3 = matrix
my_counter = Counter(matrix.T[3]).most_common(1)
i=0
for digit3 in matrix.T[3]:
if digit3 != my_counter[0][0]:
matrix3 = np.delete(matrix, i, 0)
i += 1
matrix = matrix3
print (matrix[0])
Your idea of converting to a numpy array is solid. You don't need to split it up-front. A series of masks and histograms will pare down the array fairly quickly.
z = np.array([6111, 7111, 6112, 6121, 6115, 6123])
The nth digits (zero-based) can be obtained with something like
nth = (z // 10**n) % 10
Counting the most frequent one can be accomplished quickly with np.bincount as shown here:
frequentest = np.argmax(np.bincount(nth))
You can select the elements that have that digit in the nth place with simply
mask = nth == frequentest
So now run this in a loop over n (going backwards):
# Input array
z = np.array([6111, 7111, 6112, 6121, 6115, 6123])
# Compute the maximum number of decimal digits in the list.
# You can just manually set this to 4 if you prefer
n = int(np.ceil(np.log10(z + 1).max()))
# Empty output array
output = np.empty(n, dtype=int)
# Loop over the number of digits in reverse.
# In this case, i will be 3, 2, 1, 0.
for i in range(n - 1, -1, -1):
# Get the ith digit from each element of z
# The operators //, ** and % are vectorized: they operate
# on each element of an array to return an array
ith = (z // 10**i) % 10
# Count the number of occurrences of each number 0-9 in the ith digit
# Bincount returns an array of 10 elements. counts[0] is the number of 0s,
# counts[1] is the number of 1s, ..., counts[9] is the number of 9s
counts = np.bincount(ith)
# argmax finds the index of the maximum element: the digit with the
# highest count
output[i] = np.argmax(counts)
# Trim down the array to numbers that have the requested digit in the
# right place. ith == output[i] is a boolean mask. It is 1 where ith
# is the most common digit and 0 where it is not. Indexing with such a
# mask selects the elements at locations that are non-zero.
z = z[ith == output[i]]
As it happens, np.argmax will return the index of the first maximum count if there are multiple available, meaning that it will always select the smallest number.
You can recover the number from output with something like
>>> output
array([1, 1, 1, 6])
>>> (output * 10**np.arange(output.size)).sum()
6111
You can also just get the remaining element of z:
>>> z[0]
6111

Cannot fix "list index out of range"

I'm trying to write a simple code in python to find the first missing positive integer. My algorithm is to create an array full of zeros with the size of maximum positive integer in the input array+1 (for example if the maximum number is 7, the size of 0's array would be 8). Then I trace the input array and whenever I find a positive number I change the index value+1 in the second array to 1. This is my code:
def minPositive(a):
max_a = max(a)
b = [0]*(max_a+1) # This is the second array initialized to zero
for i in range(len(a)):
if a[i] > 0:
b[a[i]+1]= 1
for j in range(len(b)):
if j != 0:
if b[j] == 0:
return j
But when I code this I face "List index out of range". I traced my program several times but I cannot find the error.
Python indexes from 0, so a list of length n has no nth element. Likewise, a list with n+1 elements has no n+1th element.
One option is for every positive value in a (rather than the value plus 1), the index corresponding to that value in b will be set to 1. You could rewrite your function like this (simplified a bit):
def minPositive(a):
b = [1 if n in a and n > 0 else 0 for n in range(max(a) + 1)]
return b
Or you could just make your list b one element longer.

median of five points python

My data frame (df) has a list of numbers (total 1773) and I am trying to find a median for five numbers (e.g. the median of 3rd number = median (1st,2nd,3rd,4th,5th))
num
10
20
15
34
...
...
...
def median(a, b, c,d,e):
I=[a,b,c,d,e]
return I[2]
num_median = [num[0]]
for i in range(1, len(num)):
num_median = median(num[i - 1], num[i-2], num[i],num[i+1],num[i+2])
df['num_median']=num_median
IndexError: index 1773 is out of bounds for axis 0 with size 1773
Where did it go wrong and Is there any other method to compute the median?
An example which will help:
a = [0, 1, 2, 3]
print('Length={}'.format(len(a)))
print(a(4))
You are trying the same thing. The actual index of an element is one lower than the place it is. Keep in mind your exception shows you exactly where your problem is.
You need to modify:
for i in range(1, len(num) - 2):
num_median = median(num[i - 1], num[i-2], num[i],num[i+1],num[i+2])
So that your last index check will not be too large. Otherwise, when you are at the end of your array (index = 1773) you will be trying to access an index which doesn't exist (1773 + 2).

Get the pairs of values from a list according to a condition without elements repeating

I have a list of integers like:
1 3 4 4 9 7 10 (the number of elements is between 1 and 200000)
and an integer variable D, it lies between 0 and 10^9.
Let it be 5 for example.
I need to count how many pairs in the list have a difference between each other not bigger than a variable D but the tricky part is that if I took the zero element with value 1 and the first element with the value 3(the difference between them meets the condition) I can't use these elements of a list again.
For example for the sequence above the answer is 3 pairs: (1,3) (4,4) (7,9)
I wrote a code which seems to be correct but I need a hint how to change the input sequence and the variable d the way it will output wrong answer
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
i = 0
while True:
if i >= len(list_of_colors):
break
if i != len(list_of_colors) - 1:
# if the number i in list and i+1 is the same or difference between them not greater than a variable d...
if (int(list_of_colors[i]) == int(list_of_colors[i + 1])) or abs(int(list_of_colors[i]) - int(list_of_colors[i + 1])) <= d:
#print list_of_colors[i]," ",list_of_colors[i + 1]
number_of_pairs += 1 # increasing the number of the acceptable pairs
i += 2 # jump over two elements, we already counted them
continue
i += 1
print number_of_pairs
I need another algorithm to compare it with the results of my algorithm on the various range of the input sequence and the variable d
Suggest your ideas please
I have a greedy solution for this problem:
Sort the input sequence.
Parse the sorted sequence as follows:
For ith element in the sequence,
if |a[i+1]-a[i]| <= D,
then pair up the elements. Proceed to process i+2th element.
else
proceed to process i+1th element.
My solution here is to first "clean" the list what means I made the number of elements even. Then I've converted the list into a list of tuples (pairs).
My result for this example is 3 pairs in order to your condition.
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
# remove the last element if the number of elements is odd
if len(list_of_colors) % 2 != 0:
list_of_colors = list_of_colors[:-1]
# create a list of tuples
list_of_colors = [tuple(list_of_colors[i:i+2]) for i in range(0, len(list_of_colors), 2)]
for i in list_of_colors:
if (int(i[0]) == int(i[1])) or abs(int(i[0])) - int(i[1]) <= d:
number_of_pairs += 1
print number_of_pairs

create a matrix of binary representation of numbers in python

for programming the Hamming cod in sage ( a compiler based on python) I need to create a matrix in which each column is a binary representation of a number
say Hamming(3) the matrix should look like this
0 0 0 1 1 1 1
0 1 1 0 0 1 1
1 0 1 0 1 0 1
which is the binary represenation of numbers from 1 to 7.
so what i did till now is to convert any given number to it's binary representation:
i made this little function it take two values n and r
and repserent n over r bits
binrep(n,r)
x=n
L=[]
LL=[]
while (n>0):
a=int(float(n%2))
L.append(a)
n=(n-a)/2
while (len(L)<r):
L.append(0)
#print(L)
LL=L[::-1]
return LL
so now i want to collect all the LL i got and make them in one big matrix like the one above
In addition to the other ones, an answer using numpy:
import numpy as np
# we're creating the binary representation for all numbers from 0 to N-1
N = 8
# for that, we need a 1xN matrix of all the numbers
a = np.arange(N, dtype=int)[np.newaxis,:]
# we also need a log2(N)x1 matrix, for the powers of 2 on the numbers.
# floor(log(N)) is the largest component that can make up any number up to N
l = int(np.log2(N))
b = np.arange(l, dtype=int)[::-1,np.newaxis]
# This step is a bit complicated, so I'll explain it below.
print np.array(a & 2**b > 0, dtype=int)
This prints:
[[0 0 0 0 1 1 1 1]
[0 0 1 1 0 0 1 1]
[0 1 0 1 0 1 0 1]]
The line
print np.array(a & 2**b > 0, dtype=int)
does a few things at once. I'll split it up into simpler steps:
# this takes our matrix b and creates a matrix containing the powers of 2
# up to 2^log2(N) == N
# (if N is a power of 2; otherwise, up to the next one below)
powers = 2**b
# now we calculate the bit-wise and (&) for each combination from a and b.
# because a has one row, and b as one column, numpy will automatically
# broadcast all values, so the resulting array has size log2(N)xN.
u = a & powers
# this is almost what we want, but has 4's in the first row,
# 2's in the second row and 1's in the last one.
# one method of getting 1's everywhere is to divide by powers:
print u / powers
# another way is to check where u > 0, which yields an array of bools,
# which we then convert to numbers by turning it into an array of ints.
print np.array(u > 0, dtype=int)
You just have to convert all those binary representations to lists of integers, collect them in a list of lists, and finally transpose that list of lists to get the desired output.
n = 3
binary = []
for i in range(1, 2**n):
s = binrep(i, n)
binary.append(map(int, s))
matrix = zip(*binary)
Or in one line: matrix = zip(*(map(int, binrep(i, n)) for i in range(1, 2**n)))
Result is
[(0, 0, 0, 1, 1, 1, 1),
(0, 1, 1, 0, 0, 1, 1),
(1, 0, 1, 0, 1, 0, 1)]
Also note that there are other ways to convert numbers to binary, e.g. using str.format:
def binrep(n,r):
return "{0:0{1}b}".format(n, r)
Like zoosuck mentioned, I would suggest the bin() function in replacement to your code. To print them in a sequence, assuming that the format is similar:
L = ['10101010', '10101010']
for i in L:
print ' '.join([j for j in i])
In a similar manner, you can append it to a list or a dictionary.

Categories

Resources