J_code
J_code

Reputation: 347

Variable array creation using numpy operations

I wish to create a variable array of numbers in numpy while skipping a chunk of numbers. For instance, If I have the variables:

m = 5

k = 3

num = 50

I want to create a linearly spaced numpy array starting at num and ending at num - k, skip k numbers and continue the array generation. Then repeat this process m times. For example, the above would yield:

np.array([50, 49, 48, 47, 44, 43, 42, 41, 38, 37, 36, 35, 32, 31, 30, 29, 26, 25, 24, 23])

How can I accomplish this via Numpy?

Upvotes: 0

Views: 103

Answers (4)

Jan Christoph Terasa
Jan Christoph Terasa

Reputation: 5935

We can use a mask and np.tile:

def mask_and_tile(m=5, k=3, num=50):
    a = np.arange(num, num - 2 * m * k, -1) # create numbers
    mask = np.ones(k * 2, dtype=bool) # create mask
    mask[k+1:] = False # set appropriate elements to False
    mask = np.tile(mask, m) # repeat mask m times
    result = a[mask] # mask our numbers
    return result

Or we can use a mask and just toggle the appropriate element:

def mask(m=5, k=3, num=50):
    a = np.arange(num, num - 2 * m * k, -1) # create numbers
    mask = np.ones_like(a, dtype=bool).reshape(-1, k)
    mask[1::2] = False
    mask[1::2, 0] = True
    result = a[mask.flatten()]
    return result

Upvotes: 1

bb1
bb1

Reputation: 7863

You can try:

import numpy as np

m = 5
k = 3
num = 50
np.hstack([np.arange(num - 2*i*k, num - (2*i+1)*k - 1, -1) for i in range(m)])

It gives:

array([50, 49, 48, 47, 44, 43, 42, 41, 38, 37, 36, 35, 32, 31, 30, 29, 26,
       25, 24, 23])

Edit:

@JanChristophTerasa posted an answer (now deleted) that avoided Python loops by masking some elements of an array obtained using np.arange(). Here is a solution inspired by that idea. It works much faster than the above one:

import numpy as np

m = 5
k = 3
num = 50
x = np.arange(num, num - 2*k*m , -1).reshape(-1, 2*k)
x[:, :k+1].ravel()

Upvotes: 4

Oli
Oli

Reputation: 2602

One way of doing this is making a 2D grid and calculating each number based on its position in the grid, then flattening it to a 1D array.

import numpy as np

num=50
m=5
k=3

# coordinates in a grid of width k+1 and height m
y, x = np.mgrid[:m, :k+1]

# a=[[50-0, 50-1, 50-2, 50-3], [50-0-2*3*1, 50-1-2*3*1, ...], [50-0-2*3*2...]...]
a = num - x - 2 * k * y

print(a.ravel())

Upvotes: 0

Cute Panda
Cute Panda

Reputation: 1498

This will work fine:

import numpy as np
m = 5
k = 3
num = 50
h=0
x = np.array([])
for i in range(m):
    x = np.append(x, range(num-h,num-h-k-1,-1))
    h+=2*k
print(x)

Output

[50. 49. 48. 47. 44. 43. 42. 41. 38. 37. 36. 35. 32. 31. 30. 29. 26. 25.
 24. 23.]

Upvotes: 0

Related Questions