如何将所选元素与行中的总和值分开,对角线PANDAS上的值除外

时间:2019-03-11 17:53:27

标签: python pandas

我正在做一些统计。

我有数据框:

tag a   b    c   d   e   f   
 a  5   2    3   2   0   1
 b  2   4    3   2   0   1
 c  3   4    3   2   0   3
 d  2   4    3   2   0   1
 e  0   4    3   2   0   8
 f  1   4    3   2   0   1

我要创建新的数据框:

tag a   b    c   d   e   f   
 a  0   x    
 b      0        
 c           0       
 d               0      
 e                   0   Y  
 f                       0

其中x等于该位置上的对应元素,除以该行中除对角线上的元素以外的元素之和。因此X为:X = 2/(2+3+2+0+1)

例如Y = 8/(0+4+3+2+8)

之后,我需要再增加一列,该列将被计算:  -sum [行中的每个元素*日志(该元素的日志)]

对于这个琐碎的问题,我很抱歉,我曾经在R中工作,并且为此任务我需要在熊猫中工作。

3 个答案:

答案 0 :(得分:3)

使用np.fill_diagonal遮盖对角线元素,然后使用DataFrame.div执行索引对齐的除法操作:

u = df.set_index('tag')
np.fill_diagonal(u.values, 0)

v = u.div(u.sum(axis=1), axis=0)
v 

        a         b         c         d    e         f
tag                                                   
a    0.00  0.250000  0.375000  0.250000  0.0  0.125000
b    0.25  0.000000  0.375000  0.250000  0.0  0.125000
c    0.25  0.333333  0.000000  0.166667  0.0  0.250000
d    0.20  0.400000  0.300000  0.000000  0.0  0.100000
e    0.00  0.235294  0.176471  0.117647  0.0  0.470588
f    0.10  0.400000  0.300000  0.200000  0.0  0.000000

“此后,我需要再增加一列要计算的值:-sum [行中的每个元素*日志(该元素的)”]

您可以使用

v['log_sum'] = -np.ma.masked_invalid(v * np.log(v)).sum(1)
v

        a         b         c         d    e         f   log_sum
tag                                                             
a    0.00  0.250000  0.375000  0.250000  0.0  0.125000 -8.965402
b    0.25  0.000000  0.375000  0.250000  0.0  0.125000 -8.965402
c    0.25  0.333333  0.000000  0.166667  0.0  0.250000 -8.461294
d    0.20  0.400000  0.300000  0.000000  0.0  0.100000 -9.560926
e    0.00  0.235294  0.176471  0.117647  0.0  0.470588 -9.708363
f    0.10  0.400000  0.300000  0.200000  0.0  0.000000 -9.560926

答案 1 :(得分:1)

numpy.eye +一点算术


u = df.iloc[:, 1:].values
x, _ = df.shape
m = 1 - np.eye(x)
n = u * m
n / n.sum(1, keepdims=1)

array([[0.   , 0.25 , 0.375, 0.25 , 0.   , 0.125],
       [0.25 , 0.   , 0.375, 0.25 , 0.   , 0.125],
       [0.25 , 0.333, 0.   , 0.167, 0.   , 0.25 ],
       [0.2  , 0.4  , 0.3  , 0.   , 0.   , 0.1  ],
       [0.   , 0.235, 0.176, 0.118, 0.   , 0.471],
       [0.1  , 0.4  , 0.3  , 0.2  , 0.   , 0.   ]])

要保持原始框架,请执行以下操作:

pd.DataFrame(index=df.tag, data=n / n.sum(1, keepdims=1), columns=df.columns[1:])

        a         b         c         d    e         f
tag
a    0.00  0.250000  0.375000  0.250000  0.0  0.125000
b    0.25  0.000000  0.375000  0.250000  0.0  0.125000
c    0.25  0.333333  0.000000  0.166667  0.0  0.250000
d    0.20  0.400000  0.300000  0.000000  0.0  0.100000
e    0.00  0.235294  0.176471  0.117647  0.0  0.470588
f    0.10  0.400000  0.300000  0.200000  0.0  0.000000

答案 2 :(得分:1)

使用np.identity和布尔值的另一种可能性。

df = df.mul(~np.identity(len(df), dtype=np.bool))
df.div(df.sum(1), 0)

    a       b           c           d           e   f
a   0.00    0.250000    0.375000    0.250000    0.0 0.125000
b   0.25    0.000000    0.375000    0.250000    0.0 0.125000
c   0.25    0.333333    0.000000    0.166667    0.0 0.250000
d   0.20    0.400000    0.300000    0.000000    0.0 0.100000
e   0.00    0.235294    0.176471    0.117647    0.0 0.470588
f   0.10    0.400000    0.300000    0.200000    0.0 0.000000