【问题标题】:Group and create three new columns by condition [Low, Hit, High]按条件分组并创建三个新列 [Low, Hit, High]
【发布时间】:2022-11-07 14:09:46
【问题描述】:

我有一个大型数据集(约 5 Mio 行),其中包含机器学习训练的结果。现在我想检查结果是否达到“目标范围”。假设这个范围包含-0.25+0.25 之间的所有值。如果它在这个范围内,它是一个Hit,如果它低于Low,另一边是High

我现在将创建这三列 Hit、Low、High 并计算适用条件的每一行并将1 放入此列,另外两列将变为0。之后,我会对这些值进行分组并总结它们。但是我怀疑肯定有更好更快的方法,比如分组的时候直接计算。


数据

import pandas as pd

df = pd.DataFrame({"Type":["RF", "RF", "RF", "MLP", "MLP", "MLP"], "Value":[-1.5,-0.1,1.7,0.2,-0.7,-0.6]})

+----+--------+---------+
|    | Type   |   Value |
|----+--------+---------|
|  0 | RF     |    -1.5 | <- Low
|  1 | RF     |    -0.1 | <- Hit
|  2 | RF     |     1.7 | <- High
|  3 | MLP    |     0.2 | <- Hit
|  4 | MLP    |    -0.7 | <- Low
|  5 | MLP    |    -0.6 | <- Low
+----+--------+---------+

预期产出

pd.DataFrame({"Type":["RF", "MLP"], "Low":[1,2], "Hit":[1,1], "High":[1,0]})

+----+--------+-------+-------+--------+
|    | Type   |   Low |   Hit |   High |
|----+--------+-------+-------+--------|
|  0 | RF     |     1 |     1 |      1 |
|  1 | MLP    |     2 |     1 |      0 |
+----+--------+-------+-------+--------+

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用 cut 定义组并使用 pivot_table 重塑:

    (df.assign(group=pd.cut(df['Value'],
                            [float('-inf'), -0.25, 0.25, float('inf')],
                            labels=['Low', 'Hit', 'High']))
       .pivot_table(index='Type', columns='group', values='Value', aggfunc='count')
       .reset_index()
       .rename_axis(None, axis=1)
    )
    

    crosstab:

    (pd.crosstab(df['Type'],
                 pd.cut(df['Value'],
                        [float('-inf'), -0.25, 0.25, float('inf')],
                        labels=['Low', 'Hit', 'High'])
                 )
       .reset_index().rename_axis(None, axis=1)
     )
    

    输出:

      Type  Low  Hit  High
    0  MLP    2    1     0
    1   RF    1    1     1
    

    【讨论】:

      【解决方案2】:

      你可以用np.select assign 它然后crosstab

      c1 = df.Value<=-0.25
      c2 = df.Value>=0.25
      out = pd.crosstab(df['Type'], np.select([c1,c2], ['Low','High'], default='Hit'))
      out
      Out[32]: 
      col_0  High  Hit  Low
      Type                 
      MLP       0    1    2
      RF        1    1    1
      

      【讨论】:

        【解决方案3】:

        你可以试试这个:

        # Your code
        import pandas as pd
        
        df = pd.DataFrame({"Type":["RF", "RF", "RF", "MLP", "MLP", "MLP"], "Value":[-1.5,-0.1,1.7,0.2,-0.7,-0.6]})
        
        # Set your range 
        RANGE_MIN = -0.25
        RANGE_MAX = 0.25
        
        # --- define functions to be applied to df ---
        # evaluate if value is a low
        def eval_low(value):
            if value < RANGE_MIN:
                return 1
            else:
                return 0
        
        # evaluate if value is a high
        def eval_high(value):
            if value > RANGE_MAX:
                return 1
            else:
                return 0
        
        # evaluate if value is a hit
        def eval_hit(value):
            if value >= RANGE_MIN and value <= RANGE_MAX:
                return 1
            else:
                return 0
        
        # Evaluate the functions in new columns
        df['Low'] = df.Value.apply(eval_low)
        df['Hit'] = df.Value.apply(eval_hit)
        df['High'] = df.Value.apply(eval_high)
        
        # get the summary
        df.groupby('Type').sum()
        

        【讨论】:

        • 请注意,您可以return int(value &lt; RANGE_MIN) 而不是使用测试;)
        • 您还可以将 3 个函数组合为 1 并将最小值/最大值作为参数传递
        • 您仍然必须调用该函数三次才能获得三列,不是吗?这更明确并且同时运行
        • 当然,只是如果你有 20 个类别,这将开始变得混乱;)
        【解决方案4】:
        df.assign(Value=pd.cut(df.Value,[-np.inf,-0.25,0.25,np.inf],labels=['Low','Hit','High']))
            .groupby('Type').value_counts().reset_index()
            .pivot_table(index='Type',columns='Value',values=0)
        
        Value  Low  Hit  High
        Type                 
        MLP      2    1     0
        RF       1    1     1
        

        【讨论】:

          猜你喜欢
          • 2021-12-22
          • 2020-02-07
          • 1970-01-01
          • 1970-01-01
          • 2023-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-13
          相关资源
          最近更新 更多