Панды - возьмите побитовый аналогично и рассчитайте средневзвешенное значение на основе этого - PullRequest
1 голос
/ 11 июня 2019

У меня есть кадр данных Pandas df1 примерно так:

  ID  col1 col2 col3
0  A   1    1    1
1  B   1    1    1
2  C   1    0    1
3  D   0    0    0
4  E   1    1    1
5  F   0    1    0
6  G   1    0    0
7  H   0    1    0

и другой кадр данных df2 вот так:

  ID  col1 col2 col3 rating1  rating2
0  I   0    1    0     1        2
1  J   0    1    1     3        1
2  K   1    0    0     4        4
3  L   0    1    0     2        2

и мне нужно найти сходство (x==y).sum (не поразрядного xor) между каждой строкой df1 (кроме ID) с соответствующими строками в df2 и используйте это сходство в качестве веса для вычисления средних оценок для всех идентификаторов в df1.

Например:

Окончательные оценки A должны быть вычислены как:

rating1[A] = ( 1*1 + 2*3 + 1*4 + 1*2 ) / (1 + 2 + 1 + 1) = 13/5

Мой вывод должен быть другим кадром данных, имеющим оценки для всех идентификаторов.через df1 после вычисления среднего значения рейтингов подобия с использованием df2.

Выходной кадр данных:

  ID rating1  rating2
0  A   13/5      2
1  B   13/5      2
... and so on till ID H

Пожалуйста, помогите мне сделать это эффективно, используя функции панд.Я пытался сделать это, перебирая все строки, но и df1, и df2 - очень большие таблицы, и это занимает много времени.

Заранее спасибо.


Обновление

@ WeNYoBen ответ правильный.Хотя, в моем случае, размеры df1 и df2 намного выше, чем я показал здесь в качестве примера.

В третьей строке (из ответа @ WeNYoBen) размеры s будут len (df1) * len (df2), и оба они огромны в моем случае и дают мнеОшибка памяти.Есть ли обходной путь для этого, в том смысле, что я мог бы разбить df2 на более мелкие части и вычислить их по отдельности?

Еще раз спасибо.

1 Ответ

1 голос
/ 11 июня 2019

Это больше похоже на numpy трансляцию, чем dot

s1=df1.iloc[:,1:].values
s2=df2.iloc[:,1:-2].values
s=np.sum(s1[:,None]==s2,-1)
df1['rating1']=s.dot(df2.rating1)/s.sum(1)
df1['rating2']=s.dot(df2.rating2)/s.sum(1)
df1
Out[623]: 
  ID  col1  col2  col3   rating1   rating2
0  A     1     1     1  2.600000  2.000000
1  B     1     1     1  2.600000  2.000000
2  C     1     0     1  3.666667  3.000000
3  D     0     0     0  2.428571  2.428571
4  E     1     1     1  2.600000  2.000000
5  F     0     1     0  2.111111  2.000000
6  G     1     0     0  3.000000  3.200000
7  H     0     1     0  2.111111  2.000000
...