How to select a number from an array with given probability distribution - python-3.x

I want to select a number from a list with a given probability.
I use numpy and I have defined a list to choose from. I also have a probability distribution matching the entries of my list.
from numpy import random
a = [0, 1] # select one entry from this list
p = [0.0, 1.0] # probability distribution
print(random.choice(a, 1, p))
With the distribution p I should only receive 1. However, when I run my code, I receive 0 too often. I think my distribution doesn't really affect the selection.

From the documentation of numpy.random.choice:
choice(a, size=None, replace=True, p=None)
When you call choice(a, 1, p), the third positional argument p is used for the replace parameter1, not for the p parameter as you intend.
You either need to insert another positional argument for replace, so that p becomes the fourth positional argument:
choice(a, 1, True, p)
or explicitly pass p as a keyword argument:
choice(a, 1, p=p)
1 This works because a list can also be evaluated in a boolean context. In this case, [0.0, 1.0], as a non-empty list, would be evaluated as True.

Related

How does this function traverse the token through slicing, Can you please explain how it selects the elements in the list?

The code I'm referring to:
predicted_index = torch.argmax(predictions[0, -1, :]).item()
This is a tensor not a list, major difference being:
tensor has one specified dtype (usually float32 in PyTorch)
faster to run operations on
Your predictions are 3D tensor of which you are taking:
0th row
last column (-1 index)
all of the elements from third dimension (:)
Essentially your are left with a vector after the slicing.
torch.argmax returns the index under which the largest element resides, for example:
torch.argmax(torch.tensor([-1, 0, 1.5, 1, 0])) # would return 2'
Code of argmax is implemented in C++ and keeps the index of largest value found until now and returns the one found at the end (O(n) complexity).
.item() changes tensor to it's Python counterpart (usually float from any floating point, int from integer family type etc.).

How to use built-in `slice` to access 2-d blocks in 2-d array?

I have a 2-d numpy array, for which I would like to modify 2-d blocks (like a 3x3 sub-block on a 9x9 sudoku board). Instead of using fancy indexing, I would like to use the built-in slice. Is there a way to make this work? I am thinking that the stride argument (third arg of slice) can be used to do this somehow, but I can't quite figure it out. My attempt is below.
import numpy as np
# make sample array (dim-1)
x = np.linspace(1, 81, 81).astype(int)
i = slice(0, 3)
print(x[i])
# [1 2 3]
# make sample array (dim-2)
X = x.reshape((9, 9))
Say I wanted to access the first 3 rows and first 3 columns of X. I can do it with fancy indexing as:
print(X[:3, :3])
# [[ 1 2 3]
# [10 11 12]
# [19 20 21]]
Trying to use similar logic to the dim-1 case with slice:
j = np.array([slice(0,3), slice(0,3)]) # wrong way to acccess
print(X[j])
Throws the following error:
IndexError: arrays used as indices must be of integer (or boolean) type
If you subscript with X[:3, :3], then behind the curtains you pass a tuple, so (slice(3), slice(3)).
So you can construct a j with:
j = (slice(3), slice(3))
or you can obtain the a, b block with:
j = (slice(3*a, 3*a+3), slice(3*b, 3*b+3))
so here a=0 and b=1 for example will yield the X[0:3, 3:6] part. So a block that contains the first three rows and second three columns.
or you can make a tuple with a variable number of items. For example for an n-dimensional array, you can make an n-tuple that each has a slice(3) object:
j = (slice(3),) * n

How does this code of list comprehension with multiple variables assigned works

I have a list of strings. I need to parse and convert the string into floats and use that for a calculation.
After multiple attempts, I figured out the easiest way to do this.
List=["1x+1y+0","1x-1y+0","1x+0y-3","0x+1y-0.5"]
I need to extract the numerical coefficients of x and y
I used:
for coef in re.split('x|y', line):
float(coeff)
This was not serving the purpose and then I found out that,
for line in list:
a,b,c = [float(coef) for coef in re.split('x|y', line)]
this code works.
If I do
a=[float(coeff) for coeff in re.split('x|y',lines)]
then a is a list with coefficients of the line
[1.0, 1.0, 0.0]
[1.0, -1.0, 0.0]
[1.0, 0.0, -3.0]
[0.0, 1.0, -0.5]
However, I am struggling to understand the logic. Here we used list comprehension. How can we assign multiple variables in a list comprehension? Is the way it works as follows:
for each string element in the list, it splits the string and converts into float. And then assign the three numbers resulting from the operation to three numbers.
But how is that if we assign only one variable it is a list, but if we assign multiple variables the type is changing?
I am sorry if the question is too basic. Am new to python hence the doubt.
a, b, c = x is called sequence unpacking. It is (almost) equivalent to:
a = x[0]
b = x[1]
c = x[2]
So a,b,c = [float(coef) for coef in re.split('x|y', line)] actually means:
x = [float(coef) for coef in re.split('x|y', line)]
a = x[0]
b = x[1]
c = x[2]
But a = x is not unpacking - it's just normal assignment: it makes a reference x. The difference: in the first case you assign a list to three variables, each "gets" one item of the list. In the second case, you assign a list to one variable and that variable "gets" the whole list. Assigning a list of three numbers to two variables (a, b = [1, 2, 3]) is invalid - you get an error message saying that there are too many values to unpack.

Finding more indices in a list close to zero

I have a list of values, which represents a damping function when this is plotted (so a form of a sinusoide). This function passes the y=0 thus several times until it levels out on y=0. I need to find the index at the moment when the function passes zero for the third time.
All values are floats, so I have a function that finds the index closest to zero:
def find_index(list_, value):
array = np.asarray(list_)
idx = (np.abs(array - value)).argmin()
return idx
Where 'list_' is the list and 'value' is zero.
This function does work, but it can only retrieve the index of the first moment the damping function (and thus the list) is closest to zero. Meaning that it will show an index of zero (because the damping function starts at zero). However, I need the index of the third time when it is closest to zero.
How can I obtain the index of the third time it will be closest to zero, instead of the first time?
You are looking for a change in the sign.
import numpy as np
x = np.array([10.0, 1.0, -1.0, -2.0, 1.0, 4.0])
y = np.sign(x) # -1 or 1
print(y)
>>> [ 1. 1. -1. -1. 1. 1.]
If you calculate the difference between consecutive elements using np.diff it will be either -2 or 2, both are boolean True.
>>> [ 0. -2. 0. 2. 0.]
Now get the indices of them using np.nonzero, which returns a tuple for each dimension. Pick the first one.
idx = np.nonzero(np.diff(y))[0]
print(idx)
>>> [1 3]

how to change the type of constraint's arguments in ortools

I don't know my question is possible or not. I am using ortools to solve an optimization problem and I know in the part of conditions the argument should be defined in double type, like this:
constraints[i] = solver.Constraint(0.0 , 10,0)
But my problem is that, I don't want to use this type of argument in creating conditions. For example I want to have a list.
So I wrote this in my code:
constraints[i] = solver.Constraint([1,2,3,...])
And I got this error:
return _pywraplp.Solver_Constraint(self, *args)
NotImplementedError: Wrong number or type of arguments for overloaded
function 'Solver_Constraint'.
Possible C/C++ prototypes are:
operations_research::MPSolver::MakeRowConstraint(double,double)
operations_research::MPSolver::MakeRowConstraint()
operations_research::MPSolver::MakeRowConstraint(double,double,std::string
const &)
operations_research::MPSolver::MakeRowConstraint(std::string const &)
Is there any way to change the type of condition's argument?
My Assumptions
your constraint expression is "a sum of some lists", meaning something along the lines of what the NumPy library does: e.g., if you have two lists of values, [1, 2, 3] and [4, 5, 6], their sum would be element-wise, s.t. [1, 2, 3] + [4, 5, 6] = [1+4, 2+5, 3+6] = [5, 7, 9].
your "list constraint" is also element-wise; e.g., [x1, x2, x3] <= [1, 2, 3] means x1 <= 1, x2 <= 2 and x3 <= 3.
you're using the GLOP Linear Solver. (Everything I say below applies to the ILP/CP/CP-SAT solvers, but some of the particular method names/other details are different.)
My Answer
The thing is, ortools only lets you set scalar values (like numbers) as variables; you can't make a "list variable", so to speak.
Therefore, you'll have to make a list of scalar variables that effectively represents the same thing.
For example, let's say you wanted your "list variable" to be a list of values, each one subjected to a particular constraint which you have stored in a list. Let's say you have a list of upper bounds:
upper_bounds = [1, 2, 3, ..., n]
And you have several lists of solver variables like so:
vars1 = [
# variable bounds here are chosen arbitrarily; set them to your purposes
solver.NumVar(0, solver.infinity, 'x{0}'.format(i))
for i in range(n)
]
vars2 = [...] # you define any other variable lists in the same way
Then, you would make a list of constraint objects, one constraint for each upper bound in your list:
constraints = [
solver.Constraint(0, ubound)
for ubound in upper_bounds
]
And you insert the variables into your constraints however is dictated for your problem:
# Example expression: X1 - X2 + 0.5*X3 < UBOUND
for i in range(n):
constraints[i].SetCoefficient(vars1[i], 1)
constraints[i].SetCoefficient(vars2[i], -1)
constraints[i].SetCoefficient(vars3[i], 0.5)
Hope this helps! I recommend taking (another, if you already have) look at the examples for your particular solver. The one for GLOP can be found here.

Resources