【问题标题】:interacting over a dateframe with functions通过数据框与函数进行交互
【发布时间】:2018-04-08 19:13:50
【问题描述】:

如果我有这样的日期框架: 否

EG_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24  \
datum_von                                                                      
2017-10-12      21.69      15.36       0.87       1.42       0.76       0.65   
2017-10-13      11.85       8.08       1.39       2.86       1.02       0.55   
2017-10-14       7.83       5.88       1.87       2.04       2.29       2.18   
2017-10-15      14.64      11.28       2.62       3.35       2.13       1.25   
2017-10-16       5.11       5.82      -0.30      -0.38      -0.24      -0.10   
2017-10-17      12.09       9.61       0.20       1.09       0.39       0.57 

我想检查大于 0 的值,并在它们较低时将它们更改为零。

不知道应该如何使用函数 iterrows() 和 loc() 函数来做到这一点。

【问题讨论】:

    标签: python pandas loops pandas-loc


    【解决方案1】:

    你可以试试:

    df1 = df[df > 0].fillna(0)
    

    结果:

    In [24]: df
    Out[24]: 
         EG_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24  \
    0  2017-10-12      21.69      15.36       0.87       1.42       0.76   
    1  2017-10-13      11.85       8.08       1.39       2.86       1.02   
    2  2017-10-14       7.83       5.88       1.87       2.04       2.29   
    3  2017-10-15      14.64      11.28       2.62       3.35       2.13   
    4  2017-10-16       5.11       5.82      -0.30      -0.38      -0.24   
    5  2017-10-17      12.09       9.61       0.20       1.09       0.39   
    
       datum_von  
    0       0.65  
    1       0.55  
    2       2.18  
    3       1.25  
    4      -0.10  
    5       0.57  
    
    In [25]: df1 = df[df > 0].fillna(0)
    
    In [26]: df1
    Out[26]: 
         EG_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24  \
    0  2017-10-12      21.69      15.36       0.87       1.42       0.76   
    1  2017-10-13      11.85       8.08       1.39       2.86       1.02   
    2  2017-10-14       7.83       5.88       1.87       2.04       2.29   
    3  2017-10-15      14.64      11.28       2.62       3.35       2.13   
    4  2017-10-16       5.11       5.82       0.00       0.00       0.00   
    5  2017-10-17      12.09       9.61       0.20       1.09       0.39   
    
       datum_von  
    0       0.65  
    1       0.55  
    2       2.18  
    3       1.25  
    4       0.00  
    5       0.57 
    

    【讨论】:

    • 伟大而简单的解决方案!我很惊讶 python 如何通过一些智能函数避免循环!但是如果我想通过 iterrows() 循环访问函数的值,那么我可以比较两个日期框架如何使用 iterrows
    【解决方案2】:

    使用clip_lower:

    df = df.clip_lower(0)
    print (df)
                G_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24
    datum_von                                                                 
    2017-10-12    21.69      15.36       0.87       1.42       0.76       0.65
    2017-10-13    11.85       8.08       1.39       2.86       1.02       0.55
    2017-10-14     7.83       5.88       1.87       2.04       2.29       2.18
    2017-10-15    14.64      11.28       2.62       3.35       2.13       1.25
    2017-10-16     5.11       5.82       0.00       0.00       0.00       0.00
    2017-10-17    12.09       9.61       0.20       1.09       0.39       0.57
    

    如果第一列不是索引:

    df = df.set_index('datum_von').clip_lower(0)
    print (df)
                G_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24
    datum_von                                                                 
    2017-10-12    21.69      15.36       0.87       1.42       0.76       0.65
    2017-10-13    11.85       8.08       1.39       2.86       1.02       0.55
    2017-10-14     7.83       5.88       1.87       2.04       2.29       2.18
    2017-10-15    14.64      11.28       2.62       3.35       2.13       1.25
    2017-10-16     5.11       5.82       0.00       0.00       0.00       0.00
    2017-10-17    12.09       9.61       0.20       1.09       0.39       0.57
    

    替代解决方案:

    df = df.mask(df < 0, 0)
    print (df)
                G_00_04  NEG_04_08  NEG_08_12  NEG_12_16  NEG_16_20  NEG_20_24
    datum_von                                                                 
    2017-10-12    21.69      15.36       0.87       1.42       0.76       0.65
    2017-10-13    11.85       8.08       1.39       2.86       1.02       0.55
    2017-10-14     7.83       5.88       1.87       2.04       2.29       2.18
    2017-10-15    14.64      11.28       2.62       3.35       2.13       1.25
    2017-10-16     5.11       5.82       0.00       0.00       0.00       0.00
    2017-10-17    12.09       9.61       0.20       1.09       0.39       0.57
    

    时间安排

    df = pd.concat([df]*10000).reset_index(drop=True)
    
    In [240]: %timeit (df.applymap(lambda x: max(0.0, x)))
    10 loops, best of 3: 164 ms per loop
    
    In [241]: %timeit (df[df > 0].fillna(0))
    100 loops, best of 3: 7.05 ms per loop
    
    In [242]: %timeit (df.clip_lower(0))
    1000 loops, best of 3: 1.96 ms per loop
    
    In [243]: %timeit df.mask(df < 0, 0)
    100 loops, best of 3: 5.18 ms per loop
    

    【讨论】:

    • 我不是 OP,只是简单地尝试捕获错误TypeError: unorderable types: str() &lt;= int(),为什么会这样?
    • 因为第一列是我的解决方案中的索引
    • 下方的剪辑是否也适用于日期?我的意思是,在另一个日期替换日期 >= 一个特定日期?谢谢。
    • @Gonzalo - 难题,理论上是的
    • 奇怪,在这两种情况下仍然得到TypeError: Could not operate 0 with block values unorderable types: numpy.ndarray() &gt;= int() ...
    【解决方案3】:

    clip_lowermask 解决方案很好。

    这是另一个applymap

    df.applymap(lambda x: max(0.0, x))
    

    【讨论】:

    • TypeError: ('unorderable types: str() &gt; float()', 'occurred at index EG_00_04')
    猜你喜欢
    • 2023-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多