用 Pandas Series 中的元素填充 Pandas DataFrame 的对角线

11

给定一个带有索引的Pandas Series

import pandas as pd

s = pd.Series(data=[1,2,3],index=['a','b','c'])

如何使用Series在pandas版本> = 0.23.0中填充空DataFrame的对角线条目?

生成的DataFrame将如下所示:

  a b c
a 1 0 0
b 0 2 0
c 0 0 3

这里有一个类似的之前问题,它会用相同的值填充对角线,我的问题是要用Series中不同的值填充对角线。

提前感谢您的考虑和回复。

2个回答

16

首先创建 DataFrame,然后使用numpy.fill_diagonal

import numpy as np

s = pd.Series(data=[1,2,3],index=['a','b','c'])

df = pd.DataFrame(0, index=s.index, columns=s.index, dtype=s.dtype)

np.fill_diagonal(df.values, s)
print (df)
   a  b  c
a  1  0  0
b  0  2  0
c  0  0  3

另一种解决方案是创建一个空的2d数组,将值添加到对角线上,最后使用DataFrame构造函数:

另一种解决方案是创建一个空的2d数组,将值添加到对角线上,最后使用DataFrame构造函数:

arr = np.zeros((len(s), len(s)), dtype=s.dtype)
np.fill_diagonal(arr, s)

print (arr)
[[1 0 0]
 [0 2 0]
 [0 0 3]]

df = pd.DataFrame(arr, index=s.index, columns=s.index)
print (df)
   a  b  c
a  1  0  0
b  0  2  0
c  0  0  3

5

我不确定能否直接使用Pandas实现,但是如果您不介意使用numpy.diag()构建序列的对角线数据矩阵,然后将其插入到DataFrame中,那么这很容易实现:

diag_data = np.diag(s)  # don't need s.as_matrix(), turns out
df = pd.DataFrame(diag_data, index=s.index, columns=s.index)

   a  b  c
a  1  0  0
b  0  2  0
c  0  0  3

一句话概括:
df = pd.DataFrame(np.diag(s),
                  index=s.index,
                  columns=s.index)

与由10000个随机元素组成的Series进行时间比较:

s = pd.Series(np.random.rand(10000), index=np.arange(10000))

df = pd.DataFrame(np.diag(s), ...)
173 ms ± 2.91 ms per loop (mean ± std. dev. of 7 runs, 20 loops each)

df = pd.DataFrame(0, ...)
np.fill_diagonal(df.values, s)
212 ms ± 909 µs per loop (mean ± std. dev. of 7 runs, 20 loops each)

mat = np.zeros(...)
np.fill_diagonal(mat, s)
df = pd.DataFrame(mat, ...)
175 ms ± 3.72 ms per loop (mean ± std. dev. of 7 runs, 20 loops each)

看起来这里展示的第一和第三个选项本质上是相同的,而中间的选项最慢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接