below I put the code I would like to get the result like: 0.1, 0.2, 0.3, 0.4 .... but I get this result [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9] how can I remove those zeros after the decimal point?
squares = []
for i in range(10):
squares.append(i * (0.1))
print(squares)
You can use something like this:
>>> ['{:.2}'.format(i * 0.1) for i in range(10)]
Use the str method format to specify how many decimals to display.
squares = []
for i in range(10):
squares.append(i * (0.1))
print(*["{:.1f}".format(s) for s in squares], sep=', ')
0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9
Sup, Kozinski. Hope you're having a great time.
squares = []
for i in range(10):
squares.append(round(i * (0.1), 1)) #integers will be stored in a proper format
print(squares)
Check out this round function
Related
I need to perform something similar to the built-in torch.argmax() function on a one-dimensional tensor, but instead of picking the index of the first of the maximum values, I want to be able to pick a random index of one of the maximum values. For example:
my_tensor = torch.tensor([0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.1])
index_1 = random_max_val_index_fn(my_tensor)
index_2 = random_max_val_index_fn(my_tensor)
print(f"{index_1}, {index_2}")
> 5, 1
You can get the indexes of all the maximums first and then choose randomly from them:
def rand_argmax(tens):
max_inds, = torch.where(tens == tens.max())
return np.random.choice(max_inds)
sample runs:
>>> my_tensor = torch.tensor([0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.1])
>>> rand_argmax(my_tensor)
2
>>> rand_argmax(my_tensor)
5
>>> rand_argmax(my_tensor)
2
>>> rand_argmax(my_tensor)
1
I think this should work:
import numpy as np
import torch
your_tensor = torch.tensor([0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.1])
argmaxes = np.argwhere(your_tensor==torch.max(your_tensor)).flatten()
rand_argmax = np.random.choice(argmaxes)
print(rand_argmax)
make sure you adjust for np.random.choice to account for replacement
I am trying to write a function that returns the value of the smallest integer that needs to be multiplied for a list of floats to be all integers. I tried implementing something with the "Least Common Multiple," but I'm not sure if the math checks out...
Say I have the following list (or list-like object) of float values:
example = [0.5, 0.4, 0.2, 0.1]
How could I write a function that returns func(example) = 10 ?
Another example would be...
example = [0.05, 0.1, 0.7, 0.8]
> func(example)
20
Since...
> 20 * np.array(example)
np.array([1, 2, 14, 16])
And all are integers.
Find the largest decimal places, multiply it to the list, find gcd, and find the minimum integer multiplier.
import numpy as np
import decimal
from math import gcd
from functools import reduce
def find_gcd(lst):
x = reduce(gcd, lst)
return x
example = [0.05, 0.1, 0.7, 0.8, 0.9]
decimal_places = min([decimal.Decimal(str(val)).as_tuple().exponent for val in example])
x1 = np.array(example)
multiplier = 1/(10**decimal_places)
gcd_val = find_gcd(map(int, x1 * multiplier))
min_multipler = int(multiplier/gcd_val)
print('Minimum Integer Multipler: ', min_multipler)
If you don't like Decimal.
example = [0.05, 0.1, 0.7, 0.8, 0.9]
n_places = max([len(str(val).split('.')[1]) for val in example])
multiplier = 10**n_places
x1 = np.array(example)
gcd_val = find_gcd(map(int, x1 * multiplier))
min_multipler = int(multiplier/gcd_val)
print('Minimum Integer Multipler: ', min_multipler)
If you have an upper bound den_max on plausible denominators the fractions.Fraction class has a handy limit_denominator method.
For example:
import fractions
max_den = 1000
fractions.Fraction(1/3)
# probably not what we want
# Fraction(6004799503160661, 18014398509481984)
fractions.Fraction(1/3).limit_denominator(max_den)
# better
# Fraction(1, 3)
import sympy
example = [0.5, 0.4, 0.2, 0.1]
sympy.lcm([fractions.Fraction(x).limit_denominator(max_den).denominator for x in example])
# 10
example = [0.05, 0.1, 0.7, 0.8]
sympy.lcm([fractions.Fraction(x).limit_denominator(max_den).denominator for x in example])
# 20
Trying to generate numbers using np.random.random:
for portfolio in range(2437):
weights = np.random.random(3)
weights /= np.sum(weights)
print(weights)
It works just as expected:
[0.348674 0.329747 0.321579]
[0.215606 0.074008 0.710386]
[0.350316 0.589782 0.059901]
[0.639651 0.025353 0.334996]
[0.697505 0.171061 0.131434]
.
.
.
.
however, how do i change the numbers such that each row is is limited to 1 decimal, like:
[0.1 0.2 0.7]
[0.2 0.2 0.6]
[0.5 0.4 0.1]
.
.
.
.
You can use
In [1]: weights.round(1)
Out[2]: array([0.4, 0.5, 0.2])
The argument to round is the amount of decimal digits you want. It also accepts negative arguments, meaning rounding to a larger-than-1 power of ten:
In [2]: np.array([123, 321, 332]).round(-1)
Out[2]: array([120, 320, 330])
For visualization only, you can use np.set_printoptions:
import numpy as np
np.set_printoptions(precision=1, suppress=True)
np.random.rand(4, 4)
array([[0.8, 0.8, 0.3, 0.3],
[0.1, 0.2, 0. , 0.2],
[0.8, 0.2, 1. , 0.2],
[0.2, 0.7, 0.6, 0.2]])
you can try np.round:
weights = np.round(weights, 1)
maybe my answer is not the most efficient but there is it:
for portfolio in range(2437):
weights = np.random.random(3)
weights /= np.sum(weights)
t_weights = []
for num in weights:
num *= 10
num = int(num)
num = float(num) / 10
t_weights.append(num)
weights = t_weights
print(weights)
I need to generate list of values from provided that satisfy this requirements:
Sum of all generated values should be equal of total, only providedValues should be used to get the sum, providedValues and total can be any double.
For example:
total = 1.0
providedValues = [0.5, 0.25]
Values in output list should be randomly distributed, for example output can be: [0.5, 0.25, 0.25], [0.25, 0.5, 0.25] or [0.25, 0.25, 0.5]
In case sum can't be equal total:
total = 1.0
providedValues = [0.3]
algorithm should throw error.
Language for implementation not so matter, I'll try to read any.
This algorithm will return all the possible combinations that sum to total.
import itertools
import numpy as np
def find_combination(total, providedValues):
i = 1
rv = []
while True:
combs = list(itertools.combinations_with_replacement(providedValues,i))
validCombs = [comb for comb in combs if np.isclose(sum(comb),total)]
if validCombs:
rv.extend(validCombs)
elif not [comb for comb in combs if sum(comb) <= total]:
return rv
i += 1
Output:
>>> find_combination(1.0, [0.5, 0.25])
[(0.5, 0.5), (0.5, 0.25, 0.25), (0.25, 0.25, 0.25, 0.25)]
>>> find_combination(1.0, [0.3])
[]
If you want to get all permutations of the results, you can use
>>> set(itertools.permutations((0.5, 0.25, 0.25)))
{(0.25, 0.25, 0.5), (0.25, 0.5, 0.25), (0.5, 0.25, 0.25)}
For example:
>>> set(y for x in find_combination(1.0, [0.5, 0.25]) for y in itertools.permutations(x))
{(0.25, 0.25, 0.25, 0.25),
(0.25, 0.25, 0.5),
(0.25, 0.5, 0.25),
(0.5, 0.25, 0.25),
(0.5, 0.5)}
Here is my solution based on there are two values provided, you may want to change it for you need
from itertools import permutations, combinations
def get_scala(x,y,t):
# get list of scala combinations
# find a,b that a*x+b*y = total
scala_list = []
amax = int(t // x) # possible max scala for x
bmax = int(t // y) # possible max scala for y
for i in range(1, amax+1):
for j in range(1, bmax+1):
if i*x + j*y == t: # find the scala combination that == total
scala_list.append((i, j))
if scala_list:
return scala_list
else:
print("Warning: cannot add up to the total")
def dist(x, y, scala):
a, b = scala
# get a base list with a number of x and b number of y [x,x,y,y,y]
bl = [x]*a + [y]*b
# get permutations and using set to get rid of duplicate items
return set(permutations(bl))
for l in get_scala(0.3, 0.2, 1):
for d in dist(0.3, 0.2, l):
print(d)
the output would look look:
(0.2, 0.3, 0.2, 0.3)
(0.2, 0.2, 0.3, 0.3)
(0.3, 0.2, 0.2, 0.3)
(0.3, 0.2, 0.3, 0.2)
(0.3, 0.3, 0.2, 0.2)
(0.2, 0.3, 0.3, 0.2)
I have a list of lists that I want to re-order:
qvalues = [[0.1, 0.3, 0.6],[0.7, 0.1, 0.2],[0.3, 0.4, 0.3],[0.1, 0.3, 0.6],[0.1, 0.3, 0.6],[0.1, 0.3, 0.6]]
I know how to reorder this list if I have a list with the order I want (example here). The tricky part is getting this order.
What I have is this:
locations = [(['Loc1','Loc1'], 3), (['Loc2'], 1), (['Loc3', 'Loc3', 'Loc3'], 2)]
This is a list of tuples, where the first element of each tuple is a list with the location name, repeated for each individual in that location, and the second element is the order these individuals are in on the qvalues list (qvalues[0] is 'Loc2', qvalues[1:4] are 'Loc3' and qvalues[4:6] are 'Loc1'.
What I want is to change the order of the lists in qvalues to the order they show up in locations: First 'Loc1', then 'Loc2' and finally 'Loc3'.
This is just a small example, my real dataset has hundreds of individuals and 17 locations.
Thanks in advance for any help you may provide.
You will need to build a list of offsets and length instead of length and positions as provided in your locations list. Then, you’ll be able to reorder based on the answer you linked to:
qvalues = [[0.1, 0.3, 0.6],[0.7, 0.1, 0.2],[0.3, 0.4, 0.3],[0.1, 0.3, 0.6],[0.1, 0.3, 0.6],[0.1, 0.3, 0.6]]
locations = [(['Loc1','Loc1'], 3), (['Loc2'], 1), (['Loc3', 'Loc3', 'Loc3'], 2)]
locations_dict = {pos:(index,len(loc)) for index,(loc,pos) in enumerate(locations)}
# if python2: locations_dict = dict([(pos,(index,len(loc))) for index,(loc,pos) in enumerate(locations)])
offsets = [None]*len(locations)
def compute_offset(pos):
# compute new offset from offset and length of previous position. End of recursion at position 1: we’re at the beginning of the list
offset = sum(compute_offset(pos-1)) if pos > 1 else 0
# get index at where to store current offset + length of current location
index, length = locations_dict[pos]
offsets[index] = (offset, length)
return offsets[index]
compute_offset(len(locations))
qvalues = [qvalues[offset:offset+length] for offset,length in offsets]
You’ll end up with qvalues being a list of lists of lists instead of a "simple" list of lists. If you want to flatten it to keep your initial layout use this list comprehension instead:
qvalues = [value for offset,length in offsets for value in qvalues[offset:offset+length]]
Output with first version
[[[0.1, 0.3, 0.6], [0.1, 0.3, 0.6]], [[0.1, 0.3, 0.6]], [[0.7, 0.1, 0.2], [0.3, 0.4, 0.3], [0.1, 0.3, 0.6]]]
Output with second version
[[0.1, 0.3, 0.6], [0.1, 0.3, 0.6], [0.1, 0.3, 0.6], [0.7, 0.1, 0.2], [0.3, 0.4, 0.3], [0.1, 0.3, 0.6]]