【问题标题】:How to filter a dataframe and identify records based on a condition on multiple other columns如何根据多个其他列上的条件过滤数据框并识别记录
【发布时间】:2022-01-03 18:54:37
【问题描述】:
            id          zone  price
0        0000001           1   33.0
1        0000001           2   24.0
2        0000001           3   34.0
3        0000001           4   45.0
4        0000001           5   51.0

我有上面的 pandas 数据框,这里有多个 id(这里只显示了 1 个 id)。数据框由具有 5 个区域和 5 个价格的特定 ID 组成。这些价格应遵循以下模式

p1(1区价格)

如果出现任何异常,我们应该识别异常记录并将其打印到文件中。

在这个例子中 p3 p2 而 p1

因此应将第一 2 条记录打印到文件中

同样,必须对其中所有唯一 ID 的整个数据框执行此操作

我的数据框很大,进行此过滤和识别错误记录的最有效方法是什么?

【问题讨论】:

    标签: python pandas dataframe filter


    【解决方案1】:

    另一种方法是首先通过ascending 订单中的id 和区域sort 您的数据框,然后使用groupby.shift() 创建一个新列将下一个价格与之前的价格进行比较。然后你可以打印出价值下降的价格:

    import numpy as np 
    import pandas as pd
    
    df.sort_values(by=['id','zone'],ascending=True)
    df['increase'] = np.where(df.zone.eq(1),'no change',
                              np.where(df.groupby('id')['price'].shift(1) < df['price'],'inc','dec'))
    

    >>> df
    
        id  zone  price   increase
    0    1     1     33  no change
    1    1     2     24        dec
    2    1     3     34        inc
    3    1     4     45        inc
    4    1     5     51        inc
    5    2     1     34  no change
    6    2     2     56        inc
    7    2     3     22        dec
    8    2     4     55        inc
    9    2     5     77        inc
    10   3     1     44  no change
    11   3     2     55        inc
    12   3     3     44        dec
    13   3     4     66        inc
    14   3     5     33        dec
    
    >>> df.loc[df.increase.eq('dec')]
    
        id  zone  price increase
    1    1     2     24      dec
    7    2     3     22      dec
    12   3     3     44      dec
    14   3     5     33      dec
    

    我添加了一些额外的 ID 来尝试模仿您的真实数据。

    【讨论】:

      【解决方案2】:

      您可以在对值进行排序后计算每个组的diff,以确保区域不断增加。如果 diff ≤ 0,则价格不会严格增加,应标记行:

      s = (df.sort_values(by=['id', 'zone']) # sort rows
             .groupby('id')                  # group by id
             ['price'].diff()                # compute the diff
             .le(0)                          # flag those ≤ 0 (not increasing)
           )
      df[s|s.shift(-1)]                      # slice flagged rows + previous row
      

      示例输出:

         id  zone  price
      0   1     1   33.0
      1   1     2   24.0
      

      示例输入:

         id  zone  price
      0   1     1   33.0
      1   1     2   24.0
      2   1     3   34.0
      3   1     4   45.0
      4   1     5   51.0
      5   2     1   20.0
      6   2     2   24.0
      7   2     3   34.0
      8   2     4   45.0
      9   2     5   51.0
      
      保存到文件
      df[s|s.shift(-1)].to_csv('incorrect_prices.csv')
      

      【讨论】:

      • :D 我喜欢第二部分!
      猜你喜欢
      • 2018-12-22
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2020-08-29
      • 2019-12-09
      • 2021-04-10
      相关资源
      最近更新 更多