0

I need to specialized numpy arrays. Assume I have a function:

    def gen_array(start, end, n_cols):

It should behave like this, generating three columns where each column goes from start (inclusive) to end (exclusive):

>>> gen_array(20, 25, 3)
array([[20, 20, 20],
       [21, 21, 21],
       [22, 22, 22],
       [23, 23, 23],
       [24, 24, 24]])

My rather naïve implementation looks like this:

def gen_array(start, end, n_columns):
    a = np.arange(start, end).reshape(end-start, 1) # create a column vector from start to end
    return np.dot(a, [np.ones(n_columns)])          # replicate across n_columns

(It's okay, though not required, that the np.dot converts values to floats.)

I'm sure there's a better, more efficient and more numpy-ish way to accomplish the same thing. Suggestions?

Update

Buildin on a suggestion by @msi_gerva to use np.tile, my latest best thought is:

def gen_array(start, end, n_cols):
    return np.tile(np.arange(start, end).reshape(-1, 1), (1, n_cols))

... which seems pretty good to me.

3
  • One way to do this: a = np.tile(np.arange(20,25,1),(3,1)).T . Not very elegant (using transpose in the end), but at least a one-liner. Commented Nov 8, 2022 at 17:36
  • tile looks good - How about reshaping first: a = np.tile(np.arange(20,25)).reshape(-1,1), (1, 3)) Commented Nov 8, 2022 at 17:45
  • 1
    Instead of dot just multiply, a * np.ones(n_columns). That's a (5,1) times a (3,) broadcasting to (5,3). Commented Nov 8, 2022 at 18:59

3 Answers 3

2

In addition to numpy.arange and numpy.reshape, use numpy.repeat to extend your data.

import numpy as np

def gen_array(start, end, n_cols):
    return np.arange(start, end).repeat(n_cols).reshape(-1, n_cols)

print(gen_array(20, 25, 3))
# [[20 20 20]
#  [21 21 21]
#  [22 22 22]
#  [23 23 23]
#  [24 24 24]]
Sign up to request clarification or add additional context in comments.

1 Comment

That feels more logical (and perhaps more efficient) than using tile(). Thanks...
0

The simplest I found:

The [:,None] adds a dimension to the array.

np.arange(start, end)[:,None]*np.ones(n_cols)

2 Comments

Yes, but that doesn't allow you to specify the number of columns as a parameter. How would you create 25 columns?
I edited the answer to reflect your variable names, the [:,None] creates the extra dimension, and the np.ones determines the size via broadcasting
0
np.arange(start, end)[:, np.newaxis].repeat(n_cols, axis=1)

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.