pandas 如何在对角线上设置值并在所有行上重复?

eivnm1vs  于 2023-02-02  发布在  其他
关注(0)|答案(2)|浏览(112)

我有一个时间序列 Dataframe 填充0和不同数量的列,我想用100从第一行和第一列开始对角线填充值。我可以使用下面的问题中提出的解决方案,但它在最后一列的值填充后停止。Set values on the diagonal of pandas.DataFrame
我怎样才能让它在所有行上重复呢?
下面是我的 Dataframe :

A      B
2020-05-02 23:00:00+00:00    0.0    0.0
2020-05-03 00:00:00+00:00    0.0    0.0
2020-05-03 01:00:00+00:00    0.0    0.0
2020-05-03 02:00:00+00:00    0.0    0.0
2020-05-03 03:00:00+00:00    0.0    0.0

但是正如您所看到的,使用Numpy fill_diagonal并不能完成这项工作。

import numpy as np
np.fill_diagonal(df.values, 0)

                               A      B
2020-05-02 23:00:00+00:00  100.0    0.0
2020-05-03 00:00:00+00:00    0.0  100.0
2020-05-03 01:00:00+00:00    0.0    0.0
2020-05-03 02:00:00+00:00    0.0    0.0
2020-05-03 03:00:00+00:00    0.0    0.0

当有2列时,我希望是这样的:

A      B
2020-05-02 23:00:00+00:00  100.0    0.0
2020-05-03 00:00:00+00:00    0.0  100.0
2020-05-03 01:00:00+00:00  100.0    0.0
2020-05-03 02:00:00+00:00    0.0  100.0
2020-05-03 03:00:00+00:00  100.0    0.0
krugob8w

krugob8w1#

下面是一个基于numpy的方法,根据列数和切片数重新整形,并返回一个给定的值:

def fill_wrapped_diag(a, fill_val):
    r,c = a.shape
    r_left = c-r%c
    a_ext = np.pad(a, ((0,r_left),(0,0)))
    a_r = a_ext.reshape((r+r_left)//c, -1)
    a_r[:,::c+1] = fill_val
    return a_r.reshape(a_ext.shape)[:-r_left]
df[:] = fill_wrapped_diag(df.values, 100)
print(df)
                               A      B
2020-05-02-23:00:00+00:00  100.0    0.0
2020-05-03-00:00:00+00:00    0.0  100.0
2020-05-03-01:00:00+00:00  100.0    0.0
2020-05-03-02:00:00+00:00    0.0  100.0
2020-05-03-03:00:00+00:00  100.0    0.0

其他一些例子:

a = np.zeros((8,4))
fill_wrapped_diag(a, fill_val=100)

array([[100.,   0.,   0.,   0.],
       [  0., 100.,   0.,   0.],
       [  0.,   0., 100.,   0.],
       [  0.,   0.,   0., 100.],
       [100.,   0.,   0.,   0.],
       [  0., 100.,   0.,   0.],
       [  0.,   0., 100.,   0.],
       [  0.,   0.,   0., 100.]])

a = np.random.randint(0,10,(7,3))
fill_wrapped_diag(a, fill_val=75)

array([[75,  8,  8],
       [ 4, 75,  7],
       [ 3,  5, 75],
       [75,  5,  5],
       [ 5, 75,  2],
       [ 3,  6, 75],
       [75,  1,  8]])
tp5buhyn

tp5buhyn2#

下面是使用np.identitynp.tile的方法

s = df.shape

df.where(np.tile(np.identity(s[-1]),(s[0],1))[:s[0]] != 1,100)

相关问题