代码之家  ›  专栏  ›  技术社区  ›  Hamed

在Python中查找Dataframe子集的特征值

  •  4
  • Hamed  · 技术社区  · 10 年前

    我有一个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]] 
    

    这将提取正确的值(检查类型,它们是浮点的)。但当我试图计算 tmp 使用 np.linalg.eigvalsh 我收到一个错误

    TypeError: No loop matching the specified signature and casting
    was found for ufunc eigvalsh_lo
    

    奇怪的是,当我从一个数据帧开始时 “不适用” 被替换为 '0.0' 整个过程可以毫无问题地完成(它需要由 0.0 而不是例如 0 ). 看起来,如果数据帧的某个部分不是真实的,则子集提取不会将值转换为实数。

    有办法克服这个问题吗?

    1 回复  |  直到 10 年前
        1
  •  3
  •   Anton Protopopov    10 年前

    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数字 所有值变为浮动:

    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数字 仅适用于 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.        ])