我有一个pandas DataFrame,df。
我想提取df中所有(col,index)的列表,其值为(col,index)> 0.95。
另外,我想说明它们位于df的下对角线,不包括对角线本身。 (如果它有帮助,那就是相关性df,所以对角线是1,这不是我感兴趣的。)
我该怎么做?
答案 0 :(得分:8)
In [71]: df = DataFrame(np.arange(25).reshape(5,5))
In [72]: df
Out[72]:
0 1 2 3 4
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
4 20 21 22 23 24
这会掩盖上三角形(包括对角线)
In [73]: mask = np.ones(df.shape,dtype='bool')
In [74]: mask[np.triu_indices(len(df))] = False
In [75]: mask
Out[75]:
array([[False, False, False, False, False],
[ True, False, False, False, False],
[ True, True, False, False, False],
[ True, True, True, False, False],
[ True, True, True, True, False]], dtype=bool)
模拟您的情况(> 0.95)
In [76]: df>16
Out[76]:
0 1 2 3 4
0 False False False False False
1 False False False False False
2 False False False False False
3 False False True True True
4 True True True True True
这是您想要结果的形式
In [77]: df[(df>16)&mask]
Out[77]:
0 1 2 3 4
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN
3 NaN NaN 17 NaN NaN
4 20 21 22 23 NaN
如果你真的想要位置值
In [78]: x = ((df>16)&mask).values.nonzero()
In [79]: zip(x[0],x[1])
Out[79]: [(3, 2), (4, 0), (4, 1), (4, 2), (4, 3)]
答案 1 :(得分:7)
有两种方法可以使用df.mask
屏蔽上对角线中的值。
一种方法是使用np.triu
。这会将数组右下角的值设置为零。这是一个例子:
>>> df = pd.DataFrame({'a': [3]*5, 'b': [2]*5, 'c': [1]*5, 'd': [0]*5, 'e': [6]*5})
>>> df
a b c d e
0 3 2 1 0 6
1 3 2 1 0 6
2 3 2 1 0 6
3 3 2 1 0 6
4 3 2 1 0 6
>>> df.mask(np.triu(np.ones(df.shape, dtype=np.bool_)))
a b c d e
0 NaN NaN NaN NaN NaN
1 3 NaN NaN NaN NaN
2 3 2 NaN NaN NaN
3 3 2 1 NaN NaN
4 3 2 1 0 NaN
以下表达式也会生成相同的DataFrame:
df.mask(np.arange(df.shape[0]) >= np.arange(df.shape[1])[:, np.newaxis])
然后,您可以按常规方式查询此新DataFrame。例如:
>>> dfm = df.mask(np.triu(np.ones(df.shape, dtype=np.bool_)))
>>> dfm[dfm > 1]
a b c d e
0 NaN NaN NaN NaN NaN
1 3 NaN NaN NaN NaN
2 3 2 NaN NaN NaN
3 3 2 NaN NaN NaN
4 3 2 NaN NaN NaN
要获得所需值的索引列表,可以选择以下选项:
>>> a = dfm[dfm > 1]
>>> np.stack(a.notnull().values.nonzero()).T.tolist()
[[1, 0], [2, 0], [2, 1], [3, 0], [3, 1], [4, 0], [4, 1]]