2016-06-21 6 views
0

Работа с данными и желание создать разреженную матрицу для последующего использования в целях кластеризации.Создание разреженной матрицы в Python

fileHandle = open('data', 'r') 

for line in fileHandle: 
    json_list = [] 
    fields = line.split('\t') 
    json_list.append(fields[0]) 
    json_list.append(fields[1]) 
    json_list.append(fields[3]) 

Сейчас данные выглядит следующим образом:

term, ids, quantity 
['buick', '123,234', '500'] 
['chevy', '345,456', '300'] 
['suv','123', '100'] 

Выход я должен был бы бы так:

term, quantity, '123', '234', '345', '456', '567' 
buick, 500, 1, 1, 0, 0, 0 
chevy, 300, 0, 0, 1, 1, 0 
suv, 100, 1, 0, 0, 0, 0 

Я пытался работать с Numpy редкой библиотекой матрицы, но без успеха.

+0

В каком формате вы имеете вход (ы)? Можете ли вы перечислить код, который воспроизводит эти данные образца? – Divakar

+0

@ Divakar добавил его, спасибо за вопрос – jKraut

+0

Будет ли 'ids' всегда попадать парами? Если да, можете ли вы разделить его на две колонки? Это может быть проще в обработке. – Divakar

ответ

0

scikit_learn, вероятно, имеет инструменты, чтобы сделать это легко, но я буду демонстрировать базовые/Numpy решение Python.

Исходные данные - список списков

In [1150]: data=[['buick', '123,234', '500'], 
       ['chevy', '345,456', '300'], 
       ['suv','123', '100']] 

Я могу вытащить Verious столбцов с списковыми. Это может быть не самым быстрым в очень большом случае, но на данный момент это простой способ решить проблему по частям.

In [1151]: terms=[row[0] for row in data] 

In [1152]: terms 
Out[1152]: ['buick', 'chevy', 'suv'] 

In [1153]: quantities=[int(row[2]) for row in data] 

In [1154]: quantities 
Out[1154]: [500, 300, 100] 

Создайте список возможных идентификаторов. Я мог бы вытащить их из data, но вы, видимо, используете больший список. Они могут быть строками вместо ints.

In [1155]: idset=[123,234,345,456,567] 

In [1156]: ids=[[int(i) for i in row[1].split(',')] for row in data] 

In [1157]: ids 
Out[1157]: [[123, 234], [345, 456], [123]] 

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

In [1158]: idM=np.array([np.in1d(idset,i) for i in ids],int) 

In [1159]: idM 
Out[1159]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]]) 

Мы могли бы собрать куски по-разному.

Например структурированный массив может быть создан с помощью:

In [1161]: M=np.zeros(len(data),dtype='U10,int,(5)int') 

In [1162]: M['f0']=terms 

In [1163]: M['f1']=quantities 

In [1164]: M['f2']=idM 

In [1165]: M 
Out[1165]: 
array([('buick', 500, [1, 1, 0, 0, 0]), ('chevy', 300, [0, 0, 1, 1, 0]), 
     ('suv', 100, [1, 0, 0, 0, 0])], 
     dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<i4', (5,))]) 

idM может быть превращен в разреженную матрицу с:

In [1167]: from scipy import sparse 

In [1168]: c=sparse.coo_matrix(idM) 

In [1169]: c 
Out[1169]: 
<3x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in COOrdinate format> 

In [1170]: c.A 
Out[1170]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]]) 

В этом исследовании было легче создать более плотную массив первой , и сделать из этого редким.

Но sparse предоставляет функцию bmat, которая позволяет мне создать матрицу мультироста из списка однорядных. (См моей истории изменений для версии, которая конструирует coo входов непосредственно)

In [1220]: ll=[[sparse.coo_matrix(np.in1d(idset,i),dtype=int)] for i in ids] 

In [1221]: sparse.bmat(ll) 
Out[1221]: 
<3x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 5 stored elements in COOrdinate format> 

In [1222]: sparse.bmat(ll).A 
Out[1222]: 
array([[1, 1, 0, 0, 0], 
     [0, 0, 1, 1, 0], 
     [1, 0, 0, 0, 0]], dtype=int32) 
+0

неясным на 1158, где вы получили «идентификатор» в idM = np.array ([np.in1d ​​(idset, i) для i в ids], int) – jKraut

+0

То же, что и 'idlist' в [1155]. Я определил оба имени, но в итоге использовал 'idset'. Я получил значения из желаемой выходной таблицы. – hpaulj

0

У меня есть ленивый метод

data = [['term', 'ids', 'quantity'], 
... ['buick', ['123', '234'], 500], 
... ['chevy', ['345', '456'], 300], 
... ['suv', ['123', '567'], 100]] 
res = [] 
for i,line in enumerate(data): 
...  if i == 0: 
...   header = line 
...  else: 
...   temp = {} 
...   for j,ele in enumerate(line): 
...    if j in [0,2]: 
...     temp.update({header[j] : ele}) 
...    else: 
...     for num in line[1]: 
...      temp.update({ num:1 }) 
...   res.append(temp) 

with open(filepath,'wb') as f: 
...  w = csv.DictWriter(f,set([ k for ele in res for k in ele.keys()])) 
...  w.writeheader() 
...  w.writerows(res) 

выход

term 456 567 345 123 234 quantity 
buick    1 1 500 
chevy 1  1   300 
suv  1  1   100 

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

  • Нет связанных вопросов^_^