List Python Quantile - python

I'm making a Quantile problems and I need to do something like this
Intervals:
150-155
155-160
160-165
165-170
170-175
175-180
180-185
>> inferior_limit = 150
>> superior_limit = 185
>> range = inferior_limit - superior_limit
>> number_of_intervals = 5
Those are the variables
and I need that because I'm doing a table's interval
>> width = range/number_of_intervals
>> while inferior_limit <= superior_limit
# there is my problem
>> inferior_limit += width
>> print inferior_limit

Is this what you meant?
>>> inf, sup, delta = 150, 185, 5
>>> print '\n'.join('{}-{}'.format(x, x + delta) for x in xrange(inf, sup, delta))
150-155
155-160
160-165
165-170
170-175
175-180
180-185

>>> start, stop, step = 150, 185, 5
>>> r = range(start, stop + 1, step) # You can use xrange on py 2 for greater efficiency
>>> for x, y in zip(r, r[1:]):
print '{0}-{1}'.format(x, y)
150-155
155-160
160-165
165-170
170-175
175-180
180-185
A more efficient way of doing this is through the use of the itertools pairwise recipe.
from itertools import tee, izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
for x, y in pairwise(r):
print '{0}-{1}'.format(x, y)
Also just for fun here is a solution using itertools.starmap, since nobody ever uses it!
from itertools import starmap
print '\n'.join(starmap('{0}-{1}'.format, pairwise(r)))

Related

calculate the mid points of a vector using Python

I started to learn python from scratch. I got some issues while doing the following problem.
I have the following vector ,x_vector = (0,1,2,3,4,5,6,7,8,9). Using this vector, I need to create this new vector x1 = (-0.5,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5).
Basically the desired vector should have first element -0.5, mid points between each elements and the last element +0.5.
The code I tried so far as follows:
import numpy as np
x_vector=np.array([0,1,2,3,4,5,6,7,8,9])
x=len(x_vector)
mid=np.zeros(x+1)
for i in range (0,x):
if i==0 :
mid[i]= x_vector[i]-0.5
else :
mid[i]=(x_vector[i] + x_vector[i+1])/2
i +=1
Seems like this doesn't give the desired output. Can you one help me to figure out what can I do to get correct output?
Using itertools.pairwise:
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
res = []
res.append(min(x_vector)-0.5)
res.append(max(x_vector)+0.5)
res.extend([np.mean(z) for z in pairwise(x_vector)])
sorted(res)
Output:
[-0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]
Consider, what will happen for i = 0 and i = 1 in your loop:
mid[0] = x_vector[0] - 0.5 # = -0.5
mid[1] = (x_vector[1] + x_vector[2]) / 2 # (1 + 2) / 2 = 3 / 2 = 1 (or 1.5 if python3)
you mismatched indexes.
Try this:
for i in range (0,x):
if i == 0:
mid[i] = x_vector[i]-0.5
else :
mid[i] = (x_vector[i - 1] + x_vector[i]) / 2.0
Note, that i changed division to divide by 2.0 instead of 2 - this will make sure, that division result will be double (number with fraction) instead of integer (number without fraction, in python 2 division two integers will round to integer).
Also i += 1 is redundant, i variable in for loop will updated (overwriting your += 1 statement) every loop iteration.
It is not clear whether this is a homework, but given that you are using numpy I think it is fair game to use it as its whole potential, in this case you can just do:
import numpy as np
x_vector=np.array([0,1,2,3,4,5,6,7,8,9])
a = np.insert(x, 0, x[0] - 1)
b = np.append(x, x[-1] + 1)
mid = (a + b) / 2

Evaluating a function over a list in Python - without using loops

There is a problem in Python which involves the evaluation of a function over a list of numbers which are provided as inputs to the following function:
f(y) = sin(3y + pi/3) + cos(4y - pi/7)
I don't think MathJax tools are available on StackOverflow so the above is the best I can do.
There are four outputs to the function: An array or list containing the values obtained by the function for each element of the input list, the minimum and maximum values in the output array / list, and an array or list of the differences between successive values obtained by the function.
Here is the code so far. We assume that only sensible inputs are passed to the function.
import sympy
def minMaxDiffValues(lst):
y = sympy.symbols('y')
f = sympy.sin(3*y + sympy.pi/3) + sympy.cos(4*y - sympy.pi/7)
values = []
for n in lst:
values.append(f.subs(y,n))
differences = []
for i in range(len(values) - 1):
differences.append(values[i + 1] - values[i])
print values
print min(values)
print max(values)
print differences
As far as I know, the above code gets the job done; I've opted to work with lists, even though I am familiar with numpy. I'll replace the print statements with a single return statement; for now I'm printing the outputs to make sure that they are correct.
The only issue is that the problem prevents the use of loops; thus I am uncertain as to how to approach such a problem for the first and last function outputs.
Is it possible to write the above function without using any loops?
You could use list comprehensions:
import sympy
def minMaxDiffValues(lst):
y = sympy.symbols('y')
f = sympy.sin(3*y + sympy.pi/3) + sympy.cos(4*y - sympy.pi/7)
values = [f.subs(y,n) for n in lst]
differences = [values[i+1] - values[i] for i in range(len(values)-1)]
print(values)
print(min(values))
print(max(values))
print(differences)
If you wanted to, you could also use the pairwise recipe from the itertools module docs:
import itertools
import sympy
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
def minMaxDiffValues(lst):
y = sympy.symbols('y')
f = sympy.sin(3*y + sympy.pi/3) + sympy.cos(4*y - sympy.pi/7)
values = [f.subs(y,n) for n in lst]
differences = [y - x for (x, y) in pairwise(values)]
print(values)
print(min(values))
print(max(values))
print(differences)
Using map is a way to apply a function to a list of values in a compact fashion:
>>> from sympy import y, pi
>>> f = lambda y: sin(3*y + pi/3) + cos(4*y - pi/7)
>>> vals = list(map(f, lst))
>>> d = lambda i: vals[i] - vals[i-1]
>>> difs = list(map(d, range(1, len(vals))))
And there is no visible 'for'. But as #hpaulj notes, there's one under the hood somewhere.

Getting Test Case Run time error

Im working on this question(not Homework)
Given a list of unsorted integers,A = {a1, a2, ...,an) can you find the pair of elements that have the smallest absolute difference between them? If there are multiple pairs, find them all.
This is what i came up with:
num = int(input())
array = [int(x) for x in input().split()]
diff = []
for i in range(len(array)):
for j in array:
diff.append(array[i]- j)
total = []
for i in diff:
if i > 0:
total.append(i)
grail = min(total)
holy = []
for i in range(len(array)):
for j in array:
if ((array[i] - j) == grail):
holy.append(array[i])
holy.append(j)
final = sorted(holy)
for item in final:
print(item, end = ' ')
This runs for few cases but gets runtime error on large inputs,any suggestion i might try?
Ex:
Input = [-20 -3916237 -357920 -3620601 7374819 -7330761 30 6246457 -6461594 266854 -520 -470 ]
Output = -520 -470 -20 30
Explanation = (-470) - (-520) = 30 - (-20) = 50, which is the smallest difference.
Thanks in advance
I did not bother to check your code for correctness because the implementation has complexity of O(n^2)
for i in range(len(array)):
for j in array:
if ((array[i] - j) == grail):
holy.append(array[i])
holy.append(j)
The required answer needs to have preferable complexity of O(log n). For achieving that you need to sort the list upfront.
from unittest import TestCase
import unittest
from sys import maxsize
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
def solution(n):
n = sorted(n)
pairs = []
diff = maxsize
for l, u in pairwise(n):
if u - l <= diff:
diff = u - l
pairs.append((diff, (l,u)))
pairs = sorted(pairs)
least = pairs[0][0]
return list(map(lambda x: x[1], filter(lambda x: x[0] == least, pairs)))
class TestLeastDiffrence(TestCase):
def testSimple(self):
n = [-20, -3916237, -357920, -3620601, 7374819, -7330761, 30, 6246457, -6461594, 266854, -520, -470]
self.assertEqual(solution(n),[(-520, -470), (-20, 30)])
if __name__ == '__main__':
unittest.main()

Fastest way to xor all integers in a string

I am trying to find the fastest way of xor'ing all integers(numerals actually) in a string consecutively. The problem makes me feel that there is an simple and a fast answer I just can't think of. But here what I came up with so far.
Setup:
from operator import xor
a = "123"
Regular loop
val = 0
for i in a:
val = val ^ int(i)
print val
operations.xor with reduce
reduce(xor, map(int, list(a)))
I expected the second one to be faster but when the string grows, the difference is almost none. Is there a faster way ?
Note1: And I would like to know if it is possible using just the integer as 123 instead of the string "123". That would be unlogical because I need a list of integers, however sometimes interesting answers appear from places you never expect.
Edit: Here is the results from the methods suggested so far.
import timeit
setup = """
from operator import xor
a = "124"
b = 124
"""
p1 = """
val = 0
for i in a:
val = val ^ int(i)
val
"""
p2 = """
reduce(xor, map(int, list(a)))
"""
p3 = """
val = 0
for i in xrange(3):
val = val ^ (b % 10)
b /= 10
val
"""
p4 = """
15 & reduce(xor, map(ord, a))
"""
print 1, timeit.timeit(p1, setup=setup, number = 100000)
print 2, timeit.timeit(p2, setup=setup, number = 100000)
print 3, timeit.timeit(p3, setup=setup, number = 100000)
print 4, timeit.timeit(p4, setup=setup, number = 100000)
# Gives
1 0.251768243842
2 0.377706036384
3 0.0885620849347
4 0.140079894386
Please also note that using int(a) instead of b in process 3 makes it slower than 4.
On my (Python 3) system, this rework of the solution runs measureably faster than those shown:
from operator import xor
from functools import reduce
print(15 & reduce(xor, map(ord, a)))
If we know they are all digits, 15 & ord('5') pulls out the bits we need with less overhead than int('5'). And we can delay the logical "and", doing it just once at the end.
To use a number instead of a string, you can do:
b = 31415926535897932384626433832795028841971693993751058209749445923078164
val = 0
while b:
b, modulo = divmod(b, 10)
val ^= modulo
print(val)

finding minimal difference

I have an array A=[a1,a2,a3,a4,a5...] and I want to find two elements of the array, say A[i] and A[j] such that i is less than j and A[j]-A[i] is minimal.
Would this code do the job:
def findMinDifference(A):
Unsorted=[]
minDiff=1000000
Unsorted=A
Sorted=quickSort(A)
for i in range(0,len(Sorted)):
if i>=1:
SmallElement=Sorted[i-1]
indexOfSmaller=Unsorted.index(SmallElement)
BigElement=Sorted[i]
indexOfBig=Unsorted.index(BigElement)
if indexOfSmaller<inexOfBig:
diff=Sorted[i]-Sorted[i-1]
if diff<minDiff:
minDiff=diff
return minDiff
Your code can be updated a bit:
a = [1,2,5,9,10,20,21,45]
a, size = sorted(a), len(a)
res = [a[i + 1] - a[i] for i in xrange(size) if i+1 < size]
print "MinDiff: {0}, MaxDiff: {1}.".format(min(res), max(res))
In two words - finding min or max diff can be simplified as getting min/max element of a list that consist of differences for each pair of elements from the sorted original list of values
Using itertools pairwise recipe:
>>> from itertools import tee, izip
>>> def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
>>> nums = [1, 3, 7, 13, 9, 18, 22]
>>> min(pairwise(sorted(nums)), key=lambda x: x[1] - x[0])
(1, 3)
Not sure why the sort. You can adapt this pseudocode.
for i = 0; i < array.length; i++
for j = i + 1; j < array.length; j++
if a[j] - a[i] < min
min = a[j] - a[i]
return min
This is another approach, using more iterables and more relying on defaults:
from itertools import imap, islice, izip
def find_min_diff(iterable, sort_func=sorted):
sorted_iterable = sort_func(iterable)
return min(imap(
lambda a, b: b - a,
izip(sorted_iterable, islice(sorted_iterable, 1)),
))

Categories

Resources