2016-07-29 2 views
4

У меня есть большой файл, где каждая строка имеет пару из 8 символов. Что-то вроде:Как читать в списке краев, чтобы сделать scipy разреженную матрицу

ab1234gh iu9240gh 

на каждой линии.

Этот файл представляет собой график, и каждая строка является идентификатором узла. Я хотел бы прочитать в файле и непосредственно сделать scipy редкую матрицу смежности. Затем я запустил PCA на этой матрице, используя один из многих инструментов, доступных в python.

Есть ли опрятный способ сделать это или мне нужно сначала сделать график в ОЗУ, а затем преобразовать его в разреженную матрицу? Поскольку файл большой, я хотел бы избежать промежуточных шагов, если это возможно.

В конечном счете, я подам разреженную матрицу смежности в http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.TruncatedSVD.html#sklearn.decomposition.TruncatedSVD.

ответ

4

Я думаю, что это обычная задача в sklearn, поэтому в пакете должен быть какой-то инструмент, который делает это, или ответ в других вопросах SO. Нам нужно добавить правильный тег.

Но просто работает с моим знанием numpy и sparse, где то, что я хотел бы сделать:

Сделайте образец 2d массив - N строк, 2 колонки со значениями символов:

In [638]: A=np.array([('a','b'),('b','d'),('a','d'),('b','c'),('d','e')]) 
In [639]: A 
Out[639]: 
array([['a', 'b'], 
     ['b', 'd'], 
     ['a', 'd'], 
     ['b', 'c'], 
     ['d', 'e']], 
     dtype='<U1') 

Использование np.unique для идентификации уникальных строк и в качестве бонуса - карта из этих строк в исходный массив. Это рабочая задача этой задачи.

In [640]: k1,k2,k3=np.unique(A,return_inverse=True,return_index=True) 
In [641]: k1 
Out[641]: 
array(['a', 'b', 'c', 'd', 'e'], 
     dtype='<U1') 
In [642]: k2 
Out[642]: array([0, 1, 7, 3, 9], dtype=int32) 
In [643]: k3 
Out[643]: array([0, 1, 1, 3, 0, 3, 1, 2, 3, 4], dtype=int32) 

можно изменить, что inverse массив для идентификации строк и COL для каждой записи в A.

In [644]: rows,cols=k3.reshape(A.shape).T 
In [645]: rows 
Out[645]: array([0, 1, 0, 1, 3], dtype=int32) 
In [646]: cols 
Out[646]: array([1, 3, 3, 2, 4], dtype=int32) 

с теми тривиально построить разреженную матрицу, которая имеет 1 в каждом «intersection`.

In [648]: M=sparse.coo_matrix((np.ones(rows.shape,int),(rows,cols))) 
In [649]: M 
Out[649]: 
<4x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in COOrdinate format> 
In [650]: M.A 
Out[650]: 
array([[0, 1, 0, 1, 0], 
     [0, 0, 1, 1, 0], 
     [0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 1]]) 

первый ряд, a имеет значение в 2-е и 4-е седловины, b и d. и так далее.

============================

Первоначально я имел:

In [648]: M=sparse.coo_matrix((np.ones(k1.shape,int),(rows,cols))) 

Это неправильно , Массив data должен соответствовать rows и cols в форме. Здесь он не вызвал ошибку, потому что k1 имеет одинаковый размер. Но с другой комбинацией уникальные значения могут вызвать ошибку.

====================

Этот подход предполагает всю базу данных, A может быть загружен в память. unique, вероятно, требует использования одинаковой памяти. Первоначально матрица coo может не увеличить использование памяти, так как она будет использовать массивы, предоставляемые в качестве параметров.Но любые вычисления и/или преобразование в csr или другой формат сделают дополнительные копии.

Я могу себе представить проблемы с памятью, загрузив базу данных в куски и используя другую структуру, чтобы получить уникальные значения и отображение. Вы даже можете построить матрицу coo из кусков. Но рано или поздно вы столкнетесь с проблемами памяти. Код scikit будет делать одну или несколько копий этой разреженной матрицы.

+0

Спасибо. Можно ли это сделать без предварительного чтения во всей матрице? Это кусок куска. – eleanora

+0

В зависимости от того, что именно вы хотите, вы можете прочитать фрагмент файла куском, используя что-то похожее на [этот ответ] (http://stackoverflow.com/questions/17056382/read-file-in-chunks-ram- use-read-strings-from-binary-files), затем найдите, какие строки и столбцы должны быть заполнены. – Mahdi

+0

Я опубликовал последующую информацию о своих проблемах с тем, чтобы это работало по адресу http://stackoverflow.com/questions/38688062/converting-a-1-2gb-list-of-edges-into-a-parparse-matrix – eleanora

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