1

I'm representing an upright square lattice with a numpy array (one element is connected to the one above, one below, to the right and to the left, but not diagonally). I need to select a random element from the lattice and change it's value to a value of a random adjacent element. Is there a simple way to do this?

At the moment my best idea is to randomize from the row and column index and then try if the element has four neighbors, then try if the left is missing, then right, then top then bottom and finally to try the four corners. This seems really cumbersome.

My data is -1,+1 randomly distributed in the lattice:

lattice=np.random.uniform(low=0.0, high=1.0, size=[30,30])
lattice[lattice<0.2]=-1
lattice[lattice>0.2]=1

So say the random element is lattice[0,0], then I'm expecting the returned lattice to be

lattice[0,0]=np.random.choice([lattice[0,1], lattice[1,0]])

edit: I'm sorry for the previous misleading use of the plural.

2
  • 2
    what's your data looks like? Offer some sample input and expected output plz Commented Mar 7, 2014 at 11:13
  • Do you want to do this for all the elements in one go or one at a time? Commented Mar 7, 2014 at 13:23

1 Answer 1

1

using scipy.ndimage.generic_filter to pass a 3x3 grid around each element to a function of our choice. This function choses a random adjacent element.
The borders (values outside the original array) is set to nan, and we filter out nan's in our function so we only choose from valid elements.

import numpy as np
import scipy.ndimage as ndimage


def random_function(arr, **kwargs):
    from random import choice
    mask = ~np.isnan(arr) & kwargs['mask']
    return choice(arr[mask])

n = 5
array = np.arange(n ** 2).reshape((n, n))
cross_mask = np.zeros(9).astype(bool)
cross_mask[[1, 3, 5, 7]] = True
res = ndimage.generic_filter(array, random_function, size=3, mode='constant', cval=np.nan, extra_keywords={'mask': cross_mask})
print array
print res

results:

array:
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]]
res:
[[ 1  6  7  8  3]
 [ 6  1 12  9  8]
 [11 10  7  8  9]
 [10 17 18 17 18]
 [15 20 21 18 19]]
Sign up to request clarification or add additional context in comments.

1 Comment

This is really interesting. I would need to be able to apply this filter on a randomly chosen element instead of the whole array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.