Using probability in python - python

Let's say i have a 2D array named grid of size (N,N).The NxN array cells can either be 0 or 1.First i initialise all the array cells as 0.Then what i would like to do is iterate through the array and change 0's to 1's with given probability p.What i mean is this:
p=0.5
for i in range(0,N-1)
for j in range(0,N-1) //iteration through every cell
// grid[i][j] has p=50% chance to change from 0 to 1
How could this be implemented?

If performance matters, and you don't mind a dependency on SciPy, there's
import scipy.stats as st
grid = st.bernoulli.rvs(0.5, size=(N, N))
or NumPy's
import numpy as np
grid = np.random.binomial(1, 0.5, size=(N, N))

I am trying a solution here.
Sample from 0-1 , according to the dimensions you want.
Then according to p, converting those > p to 1 and < p to 0 will be what you need
import numpy as np
p=0.3
N=5
(np.random.random_sample((N, N)) > p).astype(int)

Related

Find Indexes that Maps a Numpy Array to Another

If we have an numpy array a that needs to be sampled with replacement to create a second numpy array b,
import numpy as np
a = np.arange(10, 200*1000)
b = np.random.choice(a, len(a), replace=True)
What is the most efficient way to find an array of indexes named mapping that will transform a to b? It is OK to change np.random.choice to a more suitable function.
The following code is too slow and takes 7-8 seconds on a Macbook Pro to creating the mapping array. With an array size of 1 million, it will take much longer.
mapping = np.array([], dtype=np.int)
for n in b:
m = np.searchsorted(a, n)
mapping = np.append(mapping, m)
Perhaps, run the choice on index of a and slice a using this random index mapping:
mapping = np.random.choice(np.arange(len(a)), len(a), replace=True)
b = a[mapping]

Python: Initialize numpy arrays within an array of zeroes

In Python, I am trying to initialize 2-element arrays of zeros within a size N by N array. The code I'm using works but I'm looking for something more efficient and elegant:
array1 = np.empty((N,N), dtype=object)
for i in range(N):
for j in range(N):
array1[i,j] = np.zeros(2, dtype=np.int)
Thank ahead for the help
As I understand it, you should probably use a 3D array:
import numpy as np
array1 = np.empty((N,N,2), dtype=object)
which returns an array of N rows, N columns and 2 depth. If you want to pass a (NxN) array to let's say the first depth, just use:
tmp = np.ones(N,N) #for instance
array1(:,:,0) = tmp

Random diagonal matrix

I want to create a random diagonal matrix with size n such that each element in the diagonal entries has 50% chance of being -1 and 50% chance of being 1. Is there any advice for this?
import numpy as np
diagonal_entries = np.random.randint(low = -1, high = 1, size = n)
D = np.diag(diagonal_entries)
However, the problem is that `np.random.randint includes 0 as the value too. I only want -1 and 1, excluding 0.
You can use np.random.choice to sample a vector
import numpy as np
n=100
vec=np.random.choice([-1,1],n)
mat=np.diag(vec)
You can combine a few NumPy routines for a concise routine doing this:
def random_diagonal(n, proba_minus=0):
diagonal = np.ones(n)
diagonal[np.random.random(size=n) < proba_minus] = -1
return np.diagflat(diagonal)
The random routine allows you to define the probability of having "-1" and the routine np.diagflat creates a diagonal matrix from its diagonal. Both operations above are vectorized but for large sizes you need of course to know that there is a temporary array for the boolean mask.
What about something like this:
import numpy as np
diagonal_entries = np.random.randint(low = 0, high = 2, size = 4)
print diagonal_entries
# i*2-1 will map [0,1] -> [2*0-1 == -1, 2*1-1 == 1] == [-1,1]
modified = [i*2-1 for i in diagonal_entries]
D = np.diag(modified)
print D
I used the same function with a little modification on the results to suite your [-1,1] needs.
My 2nd option would be this modified = [1 if i == 1 else -1 for i in diagonal_entries]

Store indices of neighbouring cells which fall within a certain radius

I have a very large numpy array of 1s and 0s. I want to go row by row and look for all the 1s. Once I encounter a 1, I want to store the indices of entries which fall inside a radius of five rows. This is better illustrated in the picture:
(in the picture I only show half a circle, in the real case I need the indices of the values that fall inside the entire circle)
Once I collect the indices, I go to the next 1 in the array and do the same. Once I finish looping through the array I want to set all the values of the collected indices which are not 1 to 1. In a sense, I am creating a buffer around all 1s with a radius of 5 columns.
for row in myarray:
for column in myarray:
dist = math.sqrt(row**2+column**2)
if dist <= 5
.........store the indices of the neighbouring cells
Can you please give me a suggestion how to accomplish this?
The operation you are describing is called dilation. I you have scipy, you could use ndimage.binary_dilation to obtain the result:
import numpy as np
import scipy.ndimage as ndimage
import matplotlib.pyplot as plt
arr = np.zeros((21, 21))
arr[5, 5] = arr[15, 15] = 1
i, j = np.ogrid[:11, :11]
# struct = ((i-5)**2 + (j-5)**2 <= 40)
struct = np.abs(i-5)+ np.abs(j-5) <= 8
result = ndimage.binary_dilation(arr, structure=struct)
plt.imshow(result, interpolation='nearest')
plt.show()

Simple way to create matrix of random numbers

I am trying to create a matrix of random numbers, but my solution is too long and looks ugly
random_matrix = [[random.random() for e in range(2)] for e in range(3)]
this looks ok, but in my implementation it is
weights_h = [[random.random() for e in range(len(inputs[0]))] for e in range(hiden_neurons)]
which is extremely unreadable and does not fit on one line.
You can drop the range(len()):
weights_h = [[random.random() for e in inputs[0]] for e in range(hiden_neurons)]
But really, you should probably use numpy.
In [9]: numpy.random.random((3, 3))
Out[9]:
array([[ 0.37052381, 0.03463207, 0.10669077],
[ 0.05862909, 0.8515325 , 0.79809676],
[ 0.43203632, 0.54633635, 0.09076408]])
Take a look at numpy.random.rand:
Docstring: rand(d0, d1, ..., dn)
Random values in a given shape.
Create an array of the given shape and propagate it with random
samples from a uniform distribution over [0, 1).
>>> import numpy as np
>>> np.random.rand(2,3)
array([[ 0.22568268, 0.0053246 , 0.41282024],
[ 0.68824936, 0.68086462, 0.6854153 ]])
use np.random.randint() as np.random.random_integers() is deprecated
random_matrix = np.random.randint(min_val,max_val,(<num_rows>,<num_cols>))
Looks like you are doing a Python implementation of the Coursera Machine Learning Neural Network exercise. Here's what I did for randInitializeWeights(L_in, L_out)
#get a random array of floats between 0 and 1 as Pavel mentioned
W = numpy.random.random((L_out, L_in +1))
#normalize so that it spans a range of twice epsilon
W = W * 2 * epsilon
#shift so that mean is at zero
W = W - epsilon
For creating an array of random numbers NumPy provides array creation using:
Real numbers
Integers
For creating array using random Real numbers:
there are 2 options
random.rand (for uniform distribution of the generated random numbers )
random.randn (for normal distribution of the generated random numbers )
random.rand
import numpy as np
arr = np.random.rand(row_size, column_size)
random.randn
import numpy as np
arr = np.random.randn(row_size, column_size)
For creating array using random Integers:
import numpy as np
numpy.random.randint(low, high=None, size=None, dtype='l')
where
low = Lowest (signed) integer to be drawn from the distribution
high(optional)= If provided, one above the largest (signed) integer to be drawn from the distribution
size(optional) = Output shape i.e. if the given shape is, e.g., (m, n, k), then m * n * k samples are drawn
dtype(optional) = Desired dtype of the result.
eg:
The given example will produce an array of random integers between 0 and 4, its size will be 5*5 and have 25 integers
arr2 = np.random.randint(0,5,size = (5,5))
in order to create 5 by 5 matrix, it should be modified to
arr2 = np.random.randint(0,5,size = (5,5)), change the multiplication symbol* to a comma ,#
[[2 1 1 0 1][3 2 1 4 3][2 3 0 3 3][1 3 1 0 0][4 1 2 0 1]]
eg2:
The given example will produce an array of random integers between 0 and 1, its size will be 1*10 and will have 10 integers
arr3= np.random.randint(2, size = 10)
[0 0 0 0 1 1 0 0 1 1]
First, create numpy array then convert it into matrix. See the code below:
import numpy
B = numpy.random.random((3, 4)) #its ndArray
C = numpy.matrix(B)# it is matrix
print(type(B))
print(type(C))
print(C)
x = np.int_(np.random.rand(10) * 10)
For random numbers out of 10. For out of 20 we have to multiply by 20.
When you say "a matrix of random numbers", you can use numpy as Pavel https://stackoverflow.com/a/15451997/6169225 mentioned above, in this case I'm assuming to you it is irrelevant what distribution these (pseudo) random numbers adhere to.
However, if you require a particular distribution (I imagine you are interested in the uniform distribution), numpy.random has very useful methods for you. For example, let's say you want a 3x2 matrix with a pseudo random uniform distribution bounded by [low,high]. You can do this like so:
numpy.random.uniform(low,high,(3,2))
Note, you can replace uniform by any number of distributions supported by this library.
Further reading: https://docs.scipy.org/doc/numpy/reference/routines.random.html
A simple way of creating an array of random integers is:
matrix = np.random.randint(maxVal, size=(rows, columns))
The following outputs a 2 by 3 matrix of random integers from 0 to 10:
a = np.random.randint(10, size=(2,3))
random_matrix = [[random.random for j in range(collumns)] for i in range(rows)
for i in range(rows):
print random_matrix[i]
An answer using map-reduce:-
map(lambda x: map(lambda y: ran(),range(len(inputs[0]))),range(hiden_neurons))
#this is a function for a square matrix so on the while loop rows does not have to be less than cols.
#you can make your own condition. But if you want your a square matrix, use this code.
import random
import numpy as np
def random_matrix(R, cols):
matrix = []
rows = 0
while rows < cols:
N = random.sample(R, cols)
matrix.append(N)
rows = rows + 1
return np.array(matrix)
print(random_matrix(range(10), 5))
#make sure you understand the function random.sample
numpy.random.rand(row, column) generates random numbers between 0 and 1, according to the specified (m,n) parameters given. So use it to create a (m,n) matrix and multiply the matrix for the range limit and sum it with the high limit.
Analyzing: If zero is generated just the low limit will be held, but if one is generated just the high limit will be held. In order words, generating the limits using rand numpy you can generate the extreme desired numbers.
import numpy as np
high = 10
low = 5
m,n = 2,2
a = (high - low)*np.random.rand(m,n) + low
Output:
a = array([[5.91580065, 8.1117106 ],
[6.30986984, 5.720437 ]])

Categories

Resources