1

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.

3
  • That is because you set your random seed to the same number, please look in to: numpy.org/doc/stable/reference/random/generator.html Commented Jan 25, 2022 at 13:43
  • 1
    I try the same without seeding and it doesn't make a difference... The problem seems to be the construction in the final line, which only creates a single character number and then sets all the elements of the array to that character, but I'm not sure what I can do differently. Commented Jan 25, 2022 at 15:01
  • 3
    @3DspatialUser I don't think that's the problem, the problem is that only one random character is being requested: in rng.choice(68, 1) the second argument 1 is number of samples Commented Jan 25, 2022 at 15:04

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer - I got the following error when running the third line: IndexError: arrays used as indices must be of integer (or boolean) type, but it seems to work when changed to random_chars = rng.choice(char_array,size)
@celery_gemini thanks you are right, I've corrected my mistake
0
random_chars = np.array(list("abcdefghijklmnopqrstuvwxyz0123456789!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~"))
array[array=="_"] = np.random.choice(random_chars, replace=False, size=(array=="_").sum())

Comments

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.