在数据框中获取非对角元素

时间:2017-07-01 01:19:47

标签: python pandas numpy

关注pandas DataFrame diagonal,我可以使用np.diag获取对角元素。如何获取数据帧中的非对角元素(假设数据帧的大小为n x n)

3 个答案:

答案 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))

当对角元素等于0

时,不正确的初始答案

首先构建TrueFalse值的掩码,然后应用于方阵/数据帧。

xf = pd.DataFrame(np.random.rand(5,5))
diag = np.diag(np.diag(xf))
xf.mask(diag != 0)