2014-01-09 3 views
6

Предположим, у нас есть данные numpy.ndarray, скажем, с помощью формы (100,200), и у вас также есть список индексов, которые вы хотите исключить из данных. Как бы Вы это сделали? Что-то вроде этого:Как исключить строки/столбцы из данных numpy.ndarray

a = numpy.random.rand(100,200) 
indices = numpy.random.randint(100,size=20) 
b = a[-indices,:] # imaginary code, what to replace here? 

Спасибо.

ответ

7

Вы можете использовать b = numpy.delete(a, indices, axis=0)

Источник: NumPy docs.

+3

Для числового списка индексов 'np.delete' использует решение' mask', которое вы ранее отклонили, поскольку занимаете слишком много памяти. – hpaulj

+0

@hpaulj документация для 'delete' говорит: " out: ndarray Исправлена ​​копия 'arr' с элементами, указанными' obj'. Вы имеете в виду, что он использует маскированный массив 'numpy.ma'? Для меня это не похоже. –

+0

Нет, не замаскированный массив; маски как в булевом индексе. – hpaulj

2

Это некрасиво, но работает:

b = np.array([a[i] for i in range(m.shape[0]) if i not in indices]) 
0

Вы могли бы попробовать что-то вроде этого:

a = numpy.random.rand(100,200) 
indices = numpy.random.randint(100,size=20) 
mask = numpy.ones(a.shape, dtype=bool) 
mask[indices,:] = False 
b = a[mask] 
+0

Это решение нуждается в массиве тажа как мои исходные данные, которые в моем случае являются гигантскими. Сложность времени и пространства этого решения равна O (n^2), что для моих данных не очень практично. – adrin

+1

Это по существу метод, используемый 'np.delete'. Посмотрите, где он строит 'keep = ones (N, dtype = bool); keep [obj,] = False'. – hpaulj

1

Вы можете попробовать:

a = numpy.random.rand(100,200) 
indices = numpy.random.randint(100,size=20) 
b = a[np.setdiff1d(np.arange(100),indices),:] 

Это позволяет избежать создания mask массив такого же размера, что и данные в https://stackoverflow.com/a/21022753/865169. Обратите внимание, что в этом примере создается 2D-массив b вместо сплющенного массива в последнем ответе.

Грубое исследование выполнения против стоимости памяти этого подхода против https://stackoverflow.com/a/30273446/865169, кажется, предполагает, что delete быстрее при индексировании с setdiff1d гораздо проще на потреблении памяти:

In [75]: %timeit b = np.delete(a, indices, axis=0) 
The slowest run took 7.47 times longer than the fastest. This could mean that an intermediate result is being cached. 
10000 loops, best of 3: 24.7 µs per loop 

In [76]: %timeit c = a[np.setdiff1d(np.arange(100),indices),:] 
10000 loops, best of 3: 48.4 µs per loop 

In [77]: %memit b = np.delete(a, indices, axis=0) 
peak memory: 52.27 MiB, increment: 0.85 MiB 

In [78]: %memit c = a[np.setdiff1d(np.arange(100),indices),:] 
peak memory: 52.39 MiB, increment: 0.12 MiB 
Смежные вопросы