【问题标题】:Filter Pandas DataFrame using another DataFrame使用另一个 DataFrame 过滤 Pandas DataFrame
【发布时间】:2014-02-06 03:26:49
【问题描述】:

我有一个多索引 DataFrame,第一级作为组 ID,第二级作为元素名称。还有更多组,但下面只显示第一个组。

                   2000-01-04  2000-01-05 
Group Element                                     
1       A          -0.011374    0.035895 
        X          -0.006910    0.047714 
        C          -0.016609    0.038705 
        Y          -0.088110   -0.052775 
        H           0.000000    0.008082 

我有另一个 DataFrame 只包含 1 个索引,即组 ID。两者的列相同,都是日期。

         2000-01-04  2000-01-05 
Group                                     
1        -0.060623   -0.025429 
2        -0.066765   -0.005318 
3        -0.034459   -0.011243 
4        -0.051813   -0.019521 
5        -0.064367    0.014810 

我想使用第二个 DataFrame 来过滤第一个 DataFrame,方法是检查每个元素是否小于该日期组的值以获得如下结果:

                   2000-01-04  2000-01-05 
Group Element                                     
1       A          False        False     
        X          False        False     
        C          False        False     
        Y          True         True
        H          False        False     

最终,我只对为真的元素和它们为真的日期感兴趣。在日期迭代中为真的元素列表会很棒,我已经通过制作 False NaN 然后使用 dropNa() 来做到这一点。

我知道我可以编写一堆嵌套的 for 循环来做到这一点,但时间至关重要;我想不出一种在本质上和 Python 上使用 pandas 数据框结构来做到这一点的方法。任何帮助将不胜感激!

【问题讨论】:

    标签: python filter pandas


    【解决方案1】:

    您可以使用 groupby 申请:

    In [11]: g = df1.groupby(level='Group')
    
    In [12]: g.apply(lambda x: x <= df2.loc[x.name])
    Out[12]: 
                  2000-01-04 2000-01-05
    Group Element                      
    1     A            False      False
          X            False      False
          C            False      False
          Y             True       True
          H            False      False
    

    【讨论】:

    • 非常感谢!它工作得很好。只是出于兴趣,df2 值对应于每组的平均值 - 标准差。我基本上是在寻找异常值。有没有比我现在做的更好的方法?此外,这只是发现低于阈值的异常值;我正计划为上限创建另一个。但是有没有更优雅的方式呢?
    • @rmalhotra 我认为可能有,您可以访问上述 lambda 表达式中的组(如 x),因此您可以计算它......
    • 可以找到以下异常值:df.groupby(level=0).apply(lambda x: x &lt; (x.mean() - x.std() * 2)) 但是当我尝试这样做时:df.groupby(level=0).apply(lambda x: "Below" if x &lt; (x.mean() - x.std() * 2) else "False") 我得到一个值错误。另外,是否可以有多个 if 语句来检查“以上”异常值?
    • @rmalhotra 我认为你最好创建一个单独的函数(而不是把它放在一个 lambda 中),这样更容易测试。我怀疑这是一个被转换为布尔值的数组(它会在 0.13 中正确提升),你可以使用类似你的东西 .where x.where((x def f(x): mean = x.mean(); std_2 = x.std() * 2; return 1 * (x < mean - std_2) - 1 * (x > mean + std_2)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多