2016-02-26 2 views
0

Я делаю что-то о строках dedup. Мой главный рабочий поток:разреженное умножение матрицы вычисляет только верхний треугольник

df = pd.read_csv(some_path) 
vect = TfidfVectorizer(min_df=1) 
tfidf = vect.fit_transform(df.title.astype(unicode)) 

sml_matrix = (tfidf * tfidf.T) 
sml_matrix = sml_matrix> similar_ratio 

sml_matrix будет, как:

 │CHEESE CHORES GEESE GLOVES 
───────┼─────────────────────────── 
CHEESE │ 1 0.222 0.177 0.444  
CHORES │0.222  1 0.422 0.333 
GEESE │0.177 0.422  1 0.300 
GLOVES │0.444 0.333 0.300  1 

Очевидно, вычислить верхний треугольник sml_matrix является достаточно.

Но я не знаю, как вычислить только верхний треугольник с scipy.sparse матрицей (только forloop я могу себе представить, но, кажется, не так эффективно)

, например, петли (только псевдо-код):.

A = tfidf 
T = tfidf.T 
side_length = len(A) 

for i in range(side_length): 
    for j in range(side_length): 
     if j < i: 
      # avoid calculate lower triangle and diagonal 
      continue 
     maxtrix[i,j] = A(i)* T(j) 

из here, я вижу NumPy имеет np.apply_along_axis(d, 0, _) только вычислить верхний треугольник, но scipy.sparse нет.

обновление:

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

+1

Возможно, у вас возникнут проблемы с заполнением. 'tfidf * tfidf.T', вероятно, будет довольно плотным - например, если бы у вас был только один плотный столбец в' tfidf' (т.е. единственная функция, присутствующая во всех документах), тогда ваша 'sml_matrix' была бы на 100% плотной, даже если остальные ваши функции встречаются очень редко. Если вы предположили, что 'tfidf * tfidf.T' был полностью плотным, можете ли вы поместиться только в его верхний треугольник в памяти? –

ответ

1

Вероятно, вы можете выиграть фактор 2 памяти с некоторыми трюками, но размер данных всегда растет ...

Так что, кажется, лучше жить с этим, и разделить Dataframe на куски. Вы можете сделать что-то подобное:

df=pd.DataFrame(np.random.rand(12)) # as a mini exemple 
maxsize=4 
df['group']=df.index//maxsize 
df.set_index('group',append=True,inplace=True) 
df2=df.reorder_levels([1,0]) 

from itertools import combinations 

print(df) 
for i,j in (combinations(df2.index.levels[0],2)): 
    print (df2.loc[[i,j]]) 
    #or do something else. 

Тогда ФР:

    0 
    group   
0 0  0.388695 
1 0  0.982780 
2 0  0.632253 
3 0  0.445638 
4 1  0.346920 
5 1  0.789327 
6 1  0.311657 
7 1  0.548581 
8 2  0.688201 
9 2  0.824547 
10 2  0.980281 
11 2  0.314968 

И глыбы являются:

    0 
group   
0  0 0.388695 
     1 0.982780 
     2 0.632253 
     3 0.445638 
1  4 0.346920 
     5 0.789327 
     6 0.311657 
     7 0.548581 
        0 
group   
0  0 0.388695 
     1 0.982780 
     2 0.632253 
     3 0.445638 
2  8 0.688201 
     9 0.824547 
     10 0.980281 
     11 0.314968 
        0 
group   
1  4 0.346920 
     5 0.789327 
     6 0.311657 
     7 0.548581 
2  8 0.688201 
     9 0.824547 
     10 0.980281 
     11 0.314968 

Затем вычислить и собирать хорошие вещи на каждом куске. вы сделаете дважды несколько вычислений, но не более ошибок памяти.

+0

Спасибо за ответы. Я знаю, что сжатие данных может избежать ошибки памяти, но цель этого вопроса состоит в том, чтобы решить «как только вычислять верхний треугольник». – Mithril

+0

с Numpy, я не думаю, что это возможно эффективным способом. Вы можете сделать это с Numba или Cython, но поскольку точка является одной из наиболее оптимизированных функций numpy, у вас будет много работы для достижения такой же скорости. –

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