用 Pandas 系列中的元素填充 Pandas DataFrame 的对角线
Fill the diagonal of Pandas DataFrame with elements from Pandas Series
给定一个 pandas Series
和一个索引:
import pandas as pd
s = pd.Series(data=[1,2,3],index=['a','b','c'])
如何在 pandas 版本 >= 0.23.0 中使用 Series 来填充空 DataFrame 的对角线条目?
生成的 DataFrame 如下所示:
a b c
a 1 0 0
b 0 2 0
c 0 0 3
有 a prior similar question 将用相同的值填充对角线,我的问题是要求用系列中的不同值填充对角线。
提前感谢您的考虑和回复。
先创建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
构造函数:
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
我不确定直接用 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 个元素的随机数组组成的系列的时间比较:
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)
看起来这里显示的第一个和第三个选项基本相同,而中间选项最慢。
给定一个 pandas Series
和一个索引:
import pandas as pd
s = pd.Series(data=[1,2,3],index=['a','b','c'])
如何在 pandas 版本 >= 0.23.0 中使用 Series 来填充空 DataFrame 的对角线条目?
生成的 DataFrame 如下所示:
a b c
a 1 0 0
b 0 2 0
c 0 0 3
有 a prior similar question 将用相同的值填充对角线,我的问题是要求用系列中的不同值填充对角线。
提前感谢您的考虑和回复。
先创建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
构造函数:
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
我不确定直接用 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 个元素的随机数组组成的系列的时间比较:
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)
看起来这里显示的第一个和第三个选项基本相同,而中间选项最慢。