【问题标题】:Selecting data in rows based on criteria in column根据列中的条件选择行中的数据
【发布时间】:2022-12-16 16:01:29
【问题描述】:

我有两列 xls 文件,我想在 pandas 中阅读。 然后从创建的数据框中,我想根据列结果中的条件输出另一个 xls 文件。

如果结果列中的数据等于失败,则输出 xls 文件应包含上方 1 行和下方 1 行的数据以及失败行本身的数据。

显示的输入和输出示例

输入:

Team    result
1   pass
2   pass
3   fail
4   pass
5   pass
6   pass
7   fail
8   pass
9   pass
10  pass
11  pass
12  pass
13  pass
14  fail
15  pass

输出:

Team    result
2   pass
3   fail
4   pass
6   pass
7   fail
8   pass
13  pass
14  fail
15  pass

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    在从等于目标(“失败”)派生的布尔系列上使用居中的rolling总和,并执行boolean indexing

    df[df['result'].eq('fail').rolling(3, center=True, min_periods=1).max().eq(1)]
    

    注意。这使得选择下面/之后的更多行变得容易.例如,要获得上面的 2 + 下面的 2,请使用 5(一般情况下为 2*n+1)作为滚动窗口。

    输出:

        Team result
    1      2   pass
    2      3   fail
    3      4   pass
    5      6   pass
    6      7   fail
    7      8   pass
    12    13   pass
    13    14   fail
    14    15   pass
    

    【讨论】:

    • 这太棒了。但是,我想问一下 rolling 函数在这里是如何工作的,特别是当中心设置为 True 时。
    • @Anoushiravan 我不确定你不清楚什么,简而言之df['result'].eq('fail') 给出了一个布尔系列(True/False),.rolling(3, center=True, min_periods=1).max() 内部转换为1/0 并且对于每个位置,假设2*n+1 的窗口,取前 n 行和后 n 行(因此居中在给定值上)计算max。然后我们用eq(1) 转换回布尔值。这样更清楚吗?
    • 是的,我明白了,非常感谢您提供更详细的解释。
    【解决方案2】:

    shift 是你的朋友。您必须上下移动 result 列,如果其中一个值是 fail,则保留该行:

    x = (df['result'] == 'fail') | (df['result'].shift() == 'fail') | (
         df['result'].shift(-1) == 'fail')
    print(df[x])
    

    按预期给出:

        Team result
    1      2   pass
    2      3   fail
    3      4   pass
    5      6   pass
    6      7   fail
    7      8   pass
    12    13   pass
    13    14   fail
    14    15   pass
    

    【讨论】:

    • 谢谢。使用此代码,在我的输出中我只看到结果列的数据,但我也需要查看输出中包含的其他列团队数据。
    【解决方案3】:

    您可以在 df['result'] == 'fail' 的索引中加减 1,但如果最后一行有 fail,这也可能导致 KeyError。所以我们还需要使用index.intersection来达到有效索引:

    all_indexes = np.ravel([df[df['result'] == 'fail'].index + i for i in range(-1, 2)])
    valid_indexes = df.index.intersection(all_indexes)
    df.loc[valid_indexes]
    

    输出:

        result
    1   pass
    2   fail
    3   pass
    5   pass
    6   fail
    7   pass
    12  pass
    13  fail
    14  pass
    

    【讨论】:

      【解决方案4】:
      def function1(dd:pd.DataFrame):
          if dd.iloc[1,1]=='fail':
              df1.loc[dd.index,'col1']=True
          return 0
      
      pd.Series(df1.rolling(3,center=True)).apply(function1)
      df1.loc[lambda dd:dd.col1==True,:'result']
      
        Team result
      1      2   pass
      2      3   fail
      3      4   pass
      5      6   pass
      6      7   fail
      7      8   pass
      12    13   pass
      13    14   fail
      14    15   pass
      

      【讨论】:

        猜你喜欢
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-06
        • 1970-01-01
        • 2018-03-02
        相关资源
        最近更新 更多