【问题标题】:Filling a DataFrame with "sign" numbers用“符号”数字填充 DataFrame
【发布时间】:2016-09-19 12:52:26
【问题描述】:

我有一个充满浮点数(正负)和一些 NaN 的 DataFrame。 我想用它的符号替换每个浮点数:

if it's NaN -> it remains Nan
if positive -> replace with 1
if negative -> replace with -1
if zero -> leave it as 0

对进行这种大规模替换有什么建议吗?

提前谢谢你

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    代码-

    import pandas as pd
    
    
    df = pd.DataFrame({'x' : [-5.3, 2.5, 0, float('nan')]})
    
    df['x'] = df['x'].apply(func = lambda x : x if not x else x // abs(x))
    
    print(df)
    

    输出 -

        x
    0  -1
    1   1
    2   0
    3 NaN
    

    【讨论】:

    • 为什么要创建 lambda 函数? .apply(modify) 可以正常工作
    【解决方案2】:

    你可以使用np.sign:

    df
    Out[100]: 
         A
    0 -4.0
    1  2.0
    2  NaN
    3  0.0
    
    import numpy as np
    np.sign(df["A"])
    
    Out[101]: 
    0   -1.0
    1    1.0
    2    NaN
    3    0.0
    Name: A, dtype: float64
    

    为了适用于所有列,可以直接传递dataframe:

    df
    Out[121]: 
              0         1         2         3
    0 -2.932447 -1.686652       NaN -0.908441
    1  1.254436  0.000000  0.072242  0.796944
    2  2.626737  0.169639 -1.457195  1.169238
    3  0.000000 -1.174251  0.660111  1.115518
    4 -1.998091 -0.125095  0.000000 -0.506782
    
    np.sign(df)
    Out[122]: 
         0    1    2    3
    0 -1.0 -1.0  NaN -1.0
    1  1.0  0.0  1.0  1.0
    2  1.0  1.0 -1.0  1.0
    3  0.0 -1.0  1.0  1.0
    4 -1.0 -1.0  0.0 -1.0
    

    【讨论】:

    • 有没有办法解决这个给出的 Pandas 警告? A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead 这个弹出来很烦人,我需要编写额外的代码来临时隐藏警告。否则,我必须编写额外的代码,如 df['sign_A'] = -1; df.loc[np.sign(df['A'])==1, 'sign_A'] = 1; df.loc[np.sign(df['A'])==0, 'sign_A'] = 0 我只是不喜欢这需要额外的代码来消除警告......任何解决方案将不胜感激
    【解决方案3】:

    你可以使用boolean indexing:

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({'A':[-1,3,0,5],
                       'B':[4,5,6,5],
                       'C':[8,-9,np.nan,7]})
    
    print (df)
       A  B    C
    0 -1  4  8.0
    1  3  5 -9.0
    2  0  6  NaN
    3  5  5  7.0
    
    print (df > 0)
           A     B      C
    0  False  True   True
    1   True  True  False
    2  False  True  False
    3   True  True   True
    
    print (df < 0)
           A      B      C
    0   True  False  False
    1  False  False   True
    2  False  False  False
    3  False  False  False
    
    df[df > 0] = 1
    df[df < 0] = -1
    
    print (df)
       A  B    C
    0 -1  1  1.0
    1  1  1 -1.0
    2  0  1  NaN
    3  1  1  1.0
    

    【讨论】:

    • 当有另一列具有不同的数据类型(例如float)时,此方法如何工作?
    • 我认为 OP 说有浮点数和 NaN。所以我认为只有数值。
    • 你是对的,但是这种方法有什么方法可以在一般情况下工作吗?
    • 更通用的解决方案:df1 = df.fillna(1).apply(pd.to_numeric, errors='coerce') df1[df1 &gt; 0] = 1 df1[df1 &lt; 0] = -1 print (df1.fillna(df))
    • @VedangMehta 您可以对列范围进行切片或仅将操作应用于单个列。
    猜你喜欢
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多