Вычислить матрицу совпадения путем подсчета значений в ячейках
У меня есть dataframe, как это
df = pd.DataFrame({'a' : [1,1,0,0], 'b': [0,1,1,0], 'c': [0,0,1,1]})
я хочу получить
a b c
a 2 1 0
b 1 2 1
c 0 1 2
где a, b, c - имена столбцов, и я получаю значения, считающие "1" во всех столбцах, когда фильтр равен "1" в другом столбце. Для достаточно, когда df.a == 1, подсчитаем a = 2, b = 1, c = 0 и т.д.
Я сделал цикл, чтобы решить
matrix = []
for name, values in df.iteritems():
matrix.append(pd.DataFrame( df.groupby(name, as_index=False).apply(lambda x: x[x == 1].count())).values.tolist()[1])
pd.DataFrame(matrix)
Но я думаю, что есть более простое решение, не так ли?
Ответы
Ответ 1
Кажется, вам нужен матричный продукт, поэтому используйте DataFrame.dot
:
df.T.dot(df)
a b c
a 2 1 0
b 1 2 1
c 0 1 2
В качестве альтернативы, если вам нужен одинаковый уровень производительности без накладных расходов на панды, вы можете вычислить продукт с помощью np.dot
:
v = df.values
pd.DataFrame(v.T.dot(v), index=df.columns, columns=df.columns)
Или, если вы хотите получить симпатичный,
(lambda a, c: pd.DataFrame(a.T.dot(a), c, c))(df.values, df.columns)
a b c
a 2 1 0
b 1 2 1
c 0 1 2
-piRSquared
Ответ 2
np.einsum
Не так красиво, как df.T.dot(df)
но как часто вы видите np.einsum
amirite?
pd.DataFrame(np.einsum('ij,ik->jk', df, df), df.columns, df.columns)
a b c
a 2 1 0
b 1 2 1
c 0 1 2
Ответ 3
Вы можете выполнить умножение с помощью оператора @
для массивов numpy.
df = pd.DataFrame(df.values.T @ df.values, df.columns, df.columns)
Ответ 4
matmul
np.matmul(df.values.T,df.values)
Out[87]:
array([[2, 1, 0],
[1, 2, 1],
[0, 1, 2]], dtype=int64)
#pd.DataFrame(np.matmul(df.values.T,df.values), df.columns, df.columns)