20

How do I remove every nth element in an array?

import numpy as np

x = np.array([0,10,27,35,44,32,56,35,87,22,47,17])
n = 3  # remove every 3rd element

...something like the opposite of x[0::n]? I've tried this, but of course it doesn't work:

for i in np.arange(0,len(x),n):
    x = np.delete(x,i)
0

4 Answers 4

21

You're close... Pass the entire arange as subslice to delete instead of attempting to delete each element in turn, eg:

import numpy as np

x = np.array([0,10,27,35,44,32,56,35,87,22,47,17])
x = np.delete(x, np.arange(0, x.size, 3))
# [10 27 44 32 35 87 47 17]
Sign up to request clarification or add additional context in comments.

6 Comments

That is actually much better done as np.delete(x, slice(None, None, 3)).
@Jaime very nice observation - didn't think to check if np.delete took native slice objects! There doesn't seem to be any speed advantage though even with a million item array (in fact it's ever so slightly slower) - but it's good to know - thanks.
That's weird... On my system, removing every third item of a 1 million item long array is about 1.7x faster with the slice: a = np.random.rand(1e6); %timeit np.delete(a, np.arange(0, 1e6, 3)) --> 100 loops, best of 3: 14.5 ms per loop; %timeit np.delete(a, slice(None, None, 3)) --> 100 loops, best of 3: 8.41 ms per loop.
@Jaime Using that exact code: 372/365... But swaps around occasionally - umm....
@Jaime In the interests of science, I tested this as well, but on a much larger array. I got that slice was moderately faster per loop, .251 to .267 ms.
|
5

I just add another way with reshaping if the length of your array is a multiple of n:

import numpy as np

x = np.array([0,10,27,35,44,32,56,35,87,22,47,17])
x = x.reshape(-1,3)[:,1:].flatten()
# [10 27 44 32 35 87 47 17]

On my computer it runs almost twice faster than the solution with np.delete (between 1.8x and 1.9x to be honnest).

You can also easily perfom fancy operations, like m deletions each n values etc.

Comments

0

Here's a super fast version for 2D arrays: Remove every m-th row and n-th column from a 2D array (assuming the shape of the array is a multiple of (n, m)):

array2d = np.arange(60).reshape(6, 10)
m, n = (3, 5)
remove = lambda x, q: x.reshape(x.shape[0], -1, q)[..., 1:].reshape(x.shape[0], -1).T

remove(remove(array2d, n), m)

returns:

array([[11, 12, 13, 14, 16, 17, 18, 19],
       [21, 22, 23, 24, 26, 27, 28, 29],
       [41, 42, 43, 44, 46, 47, 48, 49],
       [51, 52, 53, 54, 56, 57, 58, 59]])

To generalize for any shape use padding or reduce the input array depending on your situation.


Speed comparison:

from time import time

'remove'
start = time()
for _ in range(100000):
    res = remove(remove(array2d, n), m)
time() - start

'delete'
start = time()
for _ in range(100000):
    tmp = np.delete(array2d, np.arange(0, array2d.shape[0], m), axis=0)
    res = np.delete(tmp, np.arange(0, array2d.shape[1], n), axis=1)
time() - start

"""
'remove'
0.3835930824279785
'delete'
3.173515558242798
"""

So, compared to numpy.delete the above method is significantly faster.

Comments

0

Personally, I think that @Jon Clements' answer is very suitable if you are working with numbers, but here is a generic option:

start_index = 1  
n = 5

arr = list(range(50))
arr[start_index::n] = None
elem= [elem for elem in arr if elem is not None]

This uses list slicing to set every nth element (elem) in a list (starting from index 1) to None, and then uses list comprehension to only retain elements that are not assigned None in the list. The initial value of the list (arr) is an arbitrary list of numbers between 0 (inclusive) and 50 (exclusive).

Using list comprehension is not particularly efficient, but this will work in the case when you cannot (for some reason) use external libraries, or if the elements of your list are not numeric.

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.