关注pandas DataFrame diagonal,我可以使用np.diag
获取对角元素。如何获取数据帧中的非对角元素(假设数据帧的大小为n x n)
答案 0 :(得分:5)
我将使用@Matt的相同数据框xf
xf = pd.DataFrame(np.random.rand(5, 5))
但是,我会指出,如果对角线恰好等于零,使用np.diag(np.diag(xf)) != 0
将会崩溃。
保证屏蔽对角线的方法是评估行索引不等于列索引。
选项1
numpy.indices
方便地,numpy
也通过np.indices
函数提供这些功能。
观察它们的样子
rows, cols = np.indices((5, 5))
print(rows)
[[0 0 0 0 0]
[1 1 1 1 1]
[2 2 2 2 2]
[3 3 3 3 3]
[4 4 4 4 4]]
print(cols)
[[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]]
他们是平等的......对角线。
print((cols == rows).astype(int))
[[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]]
因此,通过这些,我们可以掩饰它们与
相等的位置xf.mask(np.equal(*np.indices(xf.shape)))
0 1 2 3 4
0 NaN 0.605436 0.573386 0.978588 0.160986
1 0.295911 NaN 0.509203 0.692233 0.717464
2 0.275767 0.966976 NaN 0.883339 0.143704
3 0.628941 0.668836 0.468928 NaN 0.309901
4 0.286933 0.523243 0.693754 0.253426 NaN
我们可以用
来加快速度pd.DataFrame(
np.where(np.equal(*np.indices(xf.shape)), np.nan, xf.values),
xf.index, xf.columns
)
选项2
带有切片分配的 numpy.arange
v = xf.values.copy()
i = j = np.arange(np.min(v.shape))
v[i, j] = np.nan
pd.DataFrame(v, xf.index, xf.columns)
0 1 2 3 4
0 NaN 0.605436 0.573386 0.978588 0.160986
1 0.295911 NaN 0.509203 0.692233 0.717464
2 0.275767 0.966976 NaN 0.883339 0.143704
3 0.628941 0.668836 0.468928 NaN 0.309901
4 0.286933 0.523243 0.693754 0.253426 NaN
%%timeit
v = xf.values.copy()
i = j = np.arange(np.min(v.shape))
v[i, j] = np.nan
pd.DataFrame(v, xf.index, xf.columns)
%timeit pd.DataFrame(np.where(np.eye(np.min(xf.shape)), np.nan, xf.values), xf.index, xf.columns)
%timeit pd.DataFrame(np.where(np.equal(*np.indices(xf.shape)), np.nan, xf.values), xf.index, xf.columns)
%timeit xf.mask(np.equal(*np.indices(xf.shape)))
%timeit xf.mask(np.diag(np.diag(xf.values)) != 0)
%timeit xf.mask(np.eye(np.min(xf.shape), dtype=bool)
10000 loops, best of 3: 74.5 µs per loop
10000 loops, best of 3: 85.7 µs per loop
10000 loops, best of 3: 77 µs per loop
1000 loops, best of 3: 519 µs per loop
1000 loops, best of 3: 517 µs per loop
1000 loops, best of 3: 528 µs per loop
答案 1 :(得分:5)
使用np.eye
生成的掩码,如:
xf = pd.DataFrame(np.random.rand(5,5))
xf.mask(np.eye(5, dtype = bool))
答案 2 :(得分:0)
EDITED的答案等于SomeGuy的回答,因为当对角元素等于0
时,初始答案是错误的。
xf = pd.DataFrame(np.random.rand(5,5))
xf.mask(np.eye(5, dtype = bool))
首先构建True
和False
值的掩码,然后应用于方阵/数据帧。
xf = pd.DataFrame(np.random.rand(5,5))
diag = np.diag(np.diag(xf))
xf.mask(diag != 0)