我有一个DataFrame形式的矩阵
df= 6M 1Y 2Y 4Y 5Y 10Y 30Y
6M n/a n/a n/a n/a n/a n/a n/a
1Y n/a 1 0.9465095 0.869504 0.8124711 0.64687 0.5089244
2Y n/a 0.9465095 1 0.9343177 0.8880676 0.7423546 0.6048189
4Y n/a 0.869504 0.9343177 1 0.9762842 0.8803984 0.7760753
5Y n/a 0.8124711 0.8880676 0.9762842 1 0.9117788 0.8404656
10Y n/a 0.64687 0.7423546 0.8803984 0.9117788 1 0.9514033
30Y n/a 0.5089244 0.6048189 0.7760753 0.8404656 0.9514033 1
我从矩阵(实数)读取值,每当没有数据时我插入'n/a'
(出于其他原因需要维护此格式)。
我想计算包含浮点值的 DataFrame 子集的特征值(本质上是从 '1Y'
到 '30Y'
的子集)。
我可以使用 iloc
提取子集
tmp = df.iloc[1:df.shapep[0],1:df.shape[1]]
这会提取正确的值(检查类型,它们是 float )。但是,当我尝试使用 np.linalg.eigvalsh
计算 tmp
的特征值时,出现错误
TypeError: No loop matching the specified signature and casting
was found for ufunc eigvalsh_lo
奇怪的是,当我从 'n/a'
被 '0.0'
替换的数据帧开始时,整个过程可以毫无问题地完成(它需要由 0.0
初始化,而不是例如 0
)。
似乎如果数据帧的某些部分不是真实的,则子集提取不会将值转换为实数。
有没有办法克服这个问题?
最佳答案
IIUC 您可以使用 pd.to_numeric
将您的列转换为数字并将非数字替换为 NaN
然后使用 fillna()
你可以用 0
填充它们并使用 np.linalg.eigvals
:
In [348]: df.apply(pd.to_numeric, errors='coerce')
Out[348]:
6M 1Y 2Y 4Y 5Y 10Y 30Y
6M NaN NaN NaN NaN NaN NaN NaN
1Y NaN 1.000000 0.946509 0.869504 0.812471 0.646870 0.508924
2Y NaN 0.946509 1.000000 0.934318 0.888068 0.742355 0.604819
4Y NaN 0.869504 0.934318 1.000000 0.976284 0.880398 0.776075
5Y NaN 0.812471 0.888068 0.976284 1.000000 0.911779 0.840466
10Y NaN 0.646870 0.742355 0.880398 0.911779 1.000000 0.951403
30Y NaN 0.508924 0.604819 0.776075 0.840466 0.951403 1.000000
In [350]: df.apply(pd.to_numeric, errors='coerce').fillna(0)
Out[350]:
6M 1Y 2Y 4Y 5Y 10Y 30Y
6M 0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
1Y 0 1.000000 0.946509 0.869504 0.812471 0.646870 0.508924
2Y 0 0.946509 1.000000 0.934318 0.888068 0.742355 0.604819
4Y 0 0.869504 0.934318 1.000000 0.976284 0.880398 0.776075
5Y 0 0.812471 0.888068 0.976284 1.000000 0.911779 0.840466
10Y 0 0.646870 0.742355 0.880398 0.911779 1.000000 0.951403
30Y 0 0.508924 0.604819 0.776075 0.840466 0.951403 1.000000
In [351]: np.linalg.eigvals(df.apply(pd.to_numeric, errors='coerce').fillna(0))
Out[351]:
array([ 5.11329285, 0.7269089 , 0.07770957, 0.01334893, 0.02909796,
0.03964179, 0. ])
应用 pd.to_numeric
后所有值都变成 float :
In [352]: df.apply(pd.to_numeric, errors='coerce').dtypes
Out[352]:
6M float64
1Y float64
2Y float64
4Y float64
5Y float64
10Y float64
30Y float64
dtype: object
注意 pd.to_numeric
仅适用于 pandas
版本 >= 0.17.0
。
如果您只有 'n/a'
值,您可以使用 replace
和 astype(float)
:
df.replace('n/a', 0).astype(float)
In [364]: df.replace('n/a', 0).astype(float)
Out[364]:
6M 1Y 2Y 4Y 5Y 10Y 30Y
6M 0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
1Y 0 1.000000 0.946510 0.869504 0.812471 0.646870 0.508924
2Y 0 0.946510 1.000000 0.934318 0.888068 0.742355 0.604819
4Y 0 0.869504 0.934318 1.000000 0.976284 0.880398 0.776075
5Y 0 0.812471 0.888068 0.976284 1.000000 0.911779 0.840466
10Y 0 0.646870 0.742355 0.880398 0.911779 1.000000 0.951403
30Y 0 0.508924 0.604819 0.776075 0.840466 0.951403 1.000000
In [365]: np.linalg.eigvals(df.replace('n/a', 0).astype(float))
Out[365]:
array([ 5.11329285, 0.7269089 , 0.07770957, 0.01334893, 0.02909796,
0.03964179, 0. ])
关于python - 在 Python 中查找 Dataframe 子集的特征值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34808974/