鉴于以下数据框:
import pandas as pd
import numpy as np
a = np.arange(16).reshape(4, 4)
df = pd.DataFrame(data=a, columns=['a','b','c','d'])
我想产生以下结果:
df([[ NaN, 1, 2, 3],
[ NaN, NaN, 6, 7],
[ NaN, NaN, NaN, 11],
[ NaN, NaN, NaN, NaN]])
到目前为止,我已尝试使用np.tril_indicies
,但它仅适用于将df转换为numpy数组,并且仅适用于整数赋值(不是np.nan):
il1 = np.tril_indices(4)
a[il1] = 0
给出:
array([[ 0, 1, 2, 3],
[ 0, 0, 6, 7],
[ 0, 0, 0, 11],
[ 0, 0, 0, 0]])
......这几乎是我正在寻找的东西,但在分配NaN的时候是barf:
ValueError: cannot convert float NaN to integer
,同时:
df[il1] = 0
给出:
TypeError: unhashable type: 'numpy.ndarray'
因此,如果我想用NaN填充数据帧的底部三角形,它是否必须是一个numpy数组,或者我可以直接使用pandas吗? 2)有没有办法用NaN填充底部三角形而不是使用numpy.fill_diagonal
并在整个DataFrame中逐行递增偏移量?
另一个失败的解决方案: 用零填充np数组的对角线,然后屏蔽零并重新分配给np.nan。当它们应保留为零时,它将对角线上方的零值转换为NaN!
答案 0 :(得分:4)
您需要投放到float
a
,因为type
的{{1}}为NaN
:
float
答案 1 :(得分:4)
使用np.where
-
m,n = df.shape
df[:] = np.where(np.arange(m)[:,None] >= np.arange(n),np.nan,df)
示例运行 -
In [93]: df
Out[93]:
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
3 12 13 14 15
In [94]: m,n = df.shape
In [95]: df[:] = np.where(np.arange(m)[:,None] >= np.arange(n),np.nan,df)
In [96]: df
Out[96]:
a b c d
0 NaN 1.0 2.0 3.0
1 NaN NaN 6.0 7.0
2 NaN NaN NaN 11.0
3 NaN NaN NaN NaN