2013-12-14 4 views
5

Если у меня очень большая матрица с одним бесполезным столбцом, как я могу ее сбросить без, создавая копию исходного массива?Эффективный способ удаления столбца из массива Numpy?

np.delete(my_np_array, 0, 1) 

Приведенный выше код вернет копию массива без нулевого столбца. Но вместо этого я хотел бы просто удалить этот столбец из my_np_array, так как он мне не нужен. Для очень больших наборов данных управление памятью становится важным, и копирование может быть не вариантом.

+2

Предотвращение копирования в numpy, к сожалению, сложно. Если это первый или последний столбец, вы, вероятно, можете уйти с помощью простого среза массива. Скорее всего, это не будет копировать массив * прямо сейчас *, но если вы продолжите делать с ним более сложные вещи, нет гарантии, что позже вы не получите копии (или временные массивы) в своем коде (AFAIK). – mgilson

+0

@ Krishan Можно ли загрузить его по-другому в python? Если массив несколько генерируется из данных, можем ли мы сделать что-то, чтобы убить столбец перед рукой? Если нет, можем ли мы предварительно обработать массив другими способами, например, в 'MATLAB'? – Ray

ответ

3

Если память является основной проблемой, то вы можете перемещать столбцы внутри вашего массива так, чтобы ненужный столбец попадал в самый конец вашего массива, а затем использовал ndarray.resize, который изменяет его массив на месте, чтобы сжиматься его вниз и отбросить внешний столбец.

Вы не можете просто удалить первый столбец массива на месте с помощью предоставленного API, и я подозреваю, что это связано с memory layout of an ndarray, который отображает многомерное индексирование на одномерную байт-ориентированную адресацию в блоках смежной памяти.

Следующий пример копирует последний столбец в первый, а затем удаляет последний (теперь ненужный), немедленно очищая связанную память. Таким образом, он в основном полностью удаляет устаревший столбец из памяти за счет изменения порядка столбцов.

D1, D2 = A.shape 
A[:, 0] = A[:, D2-1] 
A.resize((D1, D2-1), refcheck=False) 
A.shape 
# => would be (5, 4) if the shape was initially (5, 5) for example 
3

Если вы используете нарезку numpy не делаете копию; другими словами

a = numpy.array([1, 2, 3, 4, 5]) 
b = a[1:] # view elements from second to last, NOT making a copy 
b[0] = 12 # Change first element of `b`, i.e. second of `a` 
print a 

ответит [1, 12, 3, 4, 5]

Если вам нужно удалить элемент в середине, однако одна нарезка не будет работать.

+1

просто добавление ... для случая OP do 'b = a [:, 1:]' –

+0

Мне было бы интересно узнать, поскольку numpy предоставляет вам новый «вид» той же структуры данных, когда вы используете slicing, когда он фактически «освобождает» память, используемую некоторым столбцом внутри нее? Другими словами, он полагается на GC Python или что-то еще? Ваше решение в основном говорит numpy, теперь вам нужно новое представление о тех же данных, вы еще не говорите, что оно может отбросить часть его. Если беспокойство OP заключалось в том, чтобы как можно быстрее освободить часть ненужной памяти, мне интересно, когда это произойдет. – matehat

+1

@matehat освобождение памяти не произойдет, поскольку представление представляет собой просто метод доступа к памяти, выделенной для массива по-разному (отбрасывается на другие типы, преобразуется/передается в другую форму, пропускает некоторые столбцы/строки и т. Д.) И может быть освобожден только полностью, а не по частям – alko

0

Многочисленные массивы неизменяемы. Поэтому они не могут быть изменены без создания промежуточной копии. How to remove specific elements in a numpy array Создание представления с нарезкой, и сделать копию этого, возможно, самое быстрое, что вы можете сделать.

In [804]: a = np.ones((2,2)) 

In [805]: a 
Out[805]: 
array([[ 1., 1.], 
     [ 1., 1.]]) 

In [806]: np.resize(a,(3,2)) 
Out[806]: 
array([[ 1., 1.], 
     [ 1., 1.], 
     [ 1., 1.]]) 

In [807]: a <- a should now be resized if it was done inplace? 
Out[807]: 
array([[ 1., 1.], 
     [ 1., 1.]]) 
+0

Согласно [документации ndarray.resize] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.resize.html#numpy.ndarray.изменение размера), массивы могут быть изменены на месте. – matehat

+0

Смотрите мои правки, я, возможно, что-то неправильно понял. – M4rtini

+0

Там 'np.resize', который возвращает новый массив, и' a.resize' (где 'a' - массив), который изменяет его размер на месте – matehat

Смежные вопросы