celerygemini
celerygemini

Reputation: 158

Replace specific elements in NumPy array with random characters

I have a NumPy array that looks like this:

array(['_', '_', '_', '_', '_', '_', '_', '_', '_', '1', '1', '_', '_',
       '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '1', '1', '1',
       '1', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_',
       '_', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'e', '_',
       '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_',
       '_', '_', '_'], dtype='<U1')

I'm looking for a way to replace the "_" characters with random choices from the ascii lowercase, digits, and punctuation characters:

abcdefghijklmnopqrstuvwxyz0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~

Note that I'm trying to get a different random character for each element, while preserving the non "_" characters as they are. I've tried this:

rng = np.random.default_rng(42)
chars = string.ascii_lowercase+string.digits+string.punctuation
array[array=="_"] = chars[rng.choice(68,1)[0]]

but it gives the same random character each time. Thanks in advance for any suggestions.

Upvotes: 1

Views: 376

Answers (2)

myrtlecat
myrtlecat

Reputation: 2276

The problem is that your code only generates a single random character! In rng.choice(68, 1), the second argument 1 is the size of the sample to generate.

To fix this, you need to generate as many random characters as you need:

# convert chars to a numpy array
char_array = np.fromiter(chars, dtype=array.dtype)

# count how many characters you need to generate
size = (array == "_").sum()

# sample chars
random_chars = rng.choice(char_array, size)

# replace "_" in array
array[array == "_"] = random_chars

Upvotes: 2

Salvatore Daniele Bianco
Salvatore Daniele Bianco

Reputation: 2691

random_chars = np.array(list("abcdefghijklmnopqrstuvwxyz0123456789!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"))
array[array=="_"] = np.random.choice(random_chars, replace=False, size=(array=="_").sum())

Upvotes: 0

Related Questions