【问题标题】:Check Results Trend using NumPy使用 NumPy 检查结果趋势
【发布时间】:2019-01-31 14:25:38
【问题描述】:

我有一个如下所述的数据框:

PROCESS_NO  PROCESS_NAME     RESULT_2    RESULT_3 
10254       AAA              4.40        46.67 
10254       AAA              4.45        48.33 
10254       AAA              4.50        50.00 
10254       AAA              4.45        48.33 
10254       AAA              4.50        50.00 
10255       BBB              4.50        50.00 
10255       BBB              4.50        50.00 
10254       AAA              4.45        48.33 
10254       AAA              4.45        48.33 
10254       AAA              4.45        48.33 
10255       BBB              4.50        51.60 
10255       BBB              4.50        52.80 
10255       BBB              4.50        56.80 
10255       BBB              4.50        51.70 
10255       BBB              4.46        57.90 
10255       BBB              4.44        52.00 

我想检查对应的 RESULT_2、RESULT_3 值是否与前 3 行值相同或更高,然后在另一列中分配 True 否则为 false 按 PROCESS_NO、PROCESS NAME 分组

我想要这样的结果数据框。

PROCESS_NO  PROCESS NAME    RESULT_2    CHECK_2 RESULT_3    CHECK_2
10254       AAA             4.40        FALSE   46.67       FALSE 
10254       AAA             4.45        FALSE   48.33       FALSE 
10254       AAA             4.45        TRUE    48.33       TRUE
10254       AAA             4.45        TRUE    48.33       TRUE
10254       AAA             4.45        TRUE    48.33       TRUE
10254       AAA             4.50        TRUE    50.00       TRUE
10254       AAA             4.45        FALSE   48.33       FALSE
10254       AAA             4.50        TRUE    50.00       TRUE
10255       BBB             4.50        FALSE   50.00       FALSE
10255       BBB             4.50        FALSE   50.00       FALSE
10255       BBB             4.50        TRUE    51.60       TRUE
10255       BBB             4.50        TRUE    52.80       TRUE
10255       BBB             4.50        TRUE    56.80       TRUE
10255       BBB             4.50        TRUE    51.70       FALSE
10255       BBB             4.46        FALSE   57.90       TRUE
10255       BBB             4.44        FALSE   52.00       FALSE

【问题讨论】:

    标签: python python-3.x pandas numpy group-by


    【解决方案1】:

    不使用 Numpy 并以最简单的方式:

    import pandas as pd
    
    data = [[10254,'AAA',4.40,46.67],
            [10255,'BBB',4.50,50.00],
            [10255,'BBB',4.50,50.00],
            [10254,'AAA',4.45,48.33],
            [10254,'AAA',4.50,50.00],
            [10254,'AAA',1.50,10.00],]
    dataframe = pd.DataFrame(data, columns=['PROCESS_NO','PROCESS NAME','RESULT_2','RESULT_3'])
    dataframe['CHECK_2'] = 'FALSE'
    dataframe['CHECK_3'] = 'FALSE'
    check2_position = dataframe.columns.get_loc('CHECK_2')
    check3_position = dataframe.columns.get_loc('CHECK_3')
    for i in range(0,len(dataframe)):
        if i >= 3 :
            current_result2 = dataframe.iloc[i]['RESULT_2'];
            if(current_result2 >= dataframe.iloc[i-1]['RESULT_2'] or
               current_result2 >= dataframe.iloc[i-2]['RESULT_2'] or
               current_result2 >= dataframe.iloc[i-3]['RESULT_2'] ):
                dataframe.iat[i,check2_position] = 'TRUE'
    
            current_result3 = dataframe.iloc[i]['RESULT_3'];
            if(current_result3 >= dataframe.iloc[i-1]['RESULT_3'] or
               current_result3 >= dataframe.iloc[i-2]['RESULT_3'] or
               current_result3 >= dataframe.iloc[i-3]['RESULT_3'] ):
                dataframe.iat[i,check3_position] = 'TRUE'
    
    
    print(dataframe)
    

    结果如你所愿:

       PROCESS_NO PROCESS NAME  RESULT_2  RESULT_3 CHECK_2 CHECK_3
    0       10254          AAA      4.40     46.67   FALSE   FALSE
    1       10255          BBB      4.50     50.00   FALSE   FALSE
    2       10255          BBB      4.50     50.00   FALSE   FALSE
    3       10254          AAA      4.45     48.33    TRUE    TRUE
    4       10254          AAA      4.50     50.00    TRUE    TRUE
    5       10254          AAA      1.50     10.00   FALSE   FALSE
    

    希望对你有帮助。

    干杯。

    【讨论】:

      【解决方案2】:

      试试这个。

      def greater_than(df_grp):
          df_grp['CHECK_2'] = df['RESULT_2'].rolling(3).apply(lambda x: all(x[2] >= i for i in x[:1]))
          df_grp['CHECK_3'] = df['RESULT_3'].rolling(3).apply(lambda x: all(x[2] >= i for i in x[:1]))
          df_grp[['CHECK_2','CHECK_3']] = df_grp[['CHECK_2','CHECK_3']].fillna(0).astype(int)
          return df_grp
      
      result = df.groupby(['PROCESS_NO', 'PROCESS NAME']).apply(greater_than)
      print(result)
      

      输出

          PROCESS_NO PROCESS NAME  RESULT_2  RESULT_3  CHECK_2  CHECK_3
      0        10254          AAA      4.40     46.67        0        0
      1        10255          BBB      4.50     50.00        0        0
      2        10255          BBB      4.50     50.00        1        1
      3        10254          AAA      4.45     48.33        0        0
      4        10254          AAA      4.45     48.33        0        0
      5        10254          AAA      4.45     48.33        1        1
      6        10254          AAA      4.45     48.33        1        1
      7        10254          AAA      4.50     50.00        1        1
      8        10255          BBB      4.50     51.60        1        1
      9        10255          BBB      4.50     52.80        1        1
      10       10255          BBB      4.50     56.80        1        1
      11       10255          BBB      4.50     51.70        1        0
      12       10255          BBB      4.50     57.90        1        1
      13       10255          BBB      4.50     52.00        1        1
      14       10254          AAA      4.45     48.33        0        0
      15       10254          AAA      4.50     50.00        1        0
      

      解释

      • 首先对 ['PROCESS_NO', 'PROCESS NAME'] 应用 groupby 方法
      • 将自定义函数应用于分组。这将分组数据框作为参数
      • 然后使用 pandas roll 围绕 3 个值(以最后一个值为中心)绘制一个窗口
      • 调用 lambda 函数检查是否所有值都小于之前的值(0 为“FALSE”,1 为“TRUE”)
      • fillna 为 0 表示没有 3 个先前值的窗口开始

      有关更多信息,请参阅: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html

      https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.rolling.html

      【讨论】:

      • 先生,我希望输出为 GrouBy PROCESS_NO & PROCESS。但是通过上述操作,我没有得到我想要的结果。
      • 对不起,我误解了你的问题。请检查我的更新答案。
      • 我正在使用 Py3.6。错误:FutureWarning:目前,“应用”将值作为 ndarrays 传递给应用函数。将来,这将更改为将其作为 Series 对象传递。您需要指定 'raw=True' 以保持当前行为,并且您可以传递 'raw=False' 以消除此警告
      • 先生,它仍然与我想要的输出不匹配。请检查我的结果。每个 PROCESS_NO 和 PROCESS 的第一两行将为零。上面的代码没有发生。
      猜你喜欢
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 2021-12-11
      • 1970-01-01
      相关资源
      最近更新 更多