通过计算单元格中的值来计算共生矩阵

Edw*_*ard 14 python dataframe pandas

我有这样的数据帧

df = pd.DataFrame({'a' : [1,1,0,0], 'b': [0,1,1,0], 'c': [0,0,1,1]})
Run Code Online (Sandbox Code Playgroud)

我想得到

  a b c
a 2 1 0
b 1 2 1
c 0 1 2
Run Code Online (Sandbox Code Playgroud)

其中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)
Run Code Online (Sandbox Code Playgroud)

但我认为有一个更简单的解决方案,不是吗?

cs9*_*s95 15

你似乎想要矩阵产品,所以杠杆DataFrame.dot:

df.T.dot(df)
   a  b  c
a  2  1  0
b  1  2  1
c  0  1  2
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要相同级别的性能而不需要大熊猫的开销,您可以使用以下方法计算产品np.dot:

v = df.values
pd.DataFrame(v.T.dot(v), index=df.columns, columns=df.columns)
Run Code Online (Sandbox Code Playgroud)

或者,如果你想变得可爱,

(lambda a, c: pd.DataFrame(a.T.dot(a), c, c))(df.values, df.columns)
Run Code Online (Sandbox Code Playgroud)

   a  b  c
a  2  1  0
b  1  2  1
c  0  1  2
Run Code Online (Sandbox Code Playgroud)

-piRSquared

  • @piRSquared哇,我偷了,呃,借这个. (2认同)

piR*_*red 10

np.einsum

不是很漂亮,df.T.dot(df)但你经常看到np.einsumamirite?

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
Run Code Online (Sandbox Code Playgroud)

  • 爱它,einsum是一个难以驯服的野兽. (2认同)

Mih*_*nut 7

您可以使用@operator为numpy数组进行乘法运算.

df = pd.DataFrame(df.values.T @ df.values, df.columns, df.columns)
Run Code Online (Sandbox Code Playgroud)

  • 很好,我也喜欢这个.可惜它只适用于3.5+!(brb,我已达到每日投票限额......) (2认同)