【问题标题】:How can I return value of a column based on the min value of one column and max value of another column?如何根据一列的最小值和另一列的最大值返回列的值?
【发布时间】:2021-10-16 13:00:56
【问题描述】:

假设我有一个像下面这样的 df,

column1 | column2 | column3  |column4  | column5 
A       |    B    |    5     |   4234  |   123   
A       |    B    |    2     |   432   |   3243  
A       |    B    |    10    |   123   |   43    
A       |    B    |    1     |   123   |   45    
A       |    B    |    1     |   124   |   23243 
A       |    B    |    1     |   125   |   234   
A       |    B    |    1     |   126   |   23    

注意:column4 始终是唯一的

所需的df,

column1 | column2 | column3  |column4  | column5 |column6
A       |    B    |    5     |   4234  |   123   |
A       |    B    |    2     |   432   |   3243  |
A       |    B    |    10    |   123   |   43    |
A       |    B    |    1     |   123   |   45    | 
A       |    B    |    1     |   124   |   23243 | 
A       |    B    |    1     |   125   |   234   |
A       |    B    |    1     |   126   |   23    | 23

我希望能够在column1和column2的基础上进行groupby,找到column3的最小值(在这种情况下-> 1)然后找到column4的最大值(在这种情况下-> 126)并返回其对应的 column6 值(在本例中为 -> 23)。

第 1 步 -> 找到给定 [['column1', 'column2']] 的最小值 1

column1 | column2 | column3      |column4  | column5 |column6
A       |    B    |    5         |         |   123   |
A       |    B    |    2         |         |   3243  |
A       |    B    |    10        |         |   43    |
A       |    B    |    **1**     |   123   |   45    | 
A       |    B    |    **1**     |   124   |   23243 | 
A       |    B    |    **1**     |   125   |   234   |
A       |    B    |    **1**     |   126   |   23    | 23

第 2 步

找到给定 [['column1', 'column2', 'column3']] 的第 4 列的最大值

column1 | column2 | column3  |column4      | column5 |column6
A       |    B    |    5     |             |   123   |
A       |    B    |    2     |             |   3243  |
A       |    B    |    10    |             |   43    |
A       |    B    |    1     |   123       |   45    | 
A       |    B    |    1     |   124       |   23243 | 
A       |    B    |    1     |   125       |   234   |
A       |    B    |    1     |   **126**   |   23    | 23

第3步返回column5对应的值23

我怎样才能做到这一点?

【问题讨论】:

  • column4 的最大值是 4234,而不是 126。
  • 不,你首先取 column3 的最小值(即 1),所以你剩下 123,124,125,126,其中 126 是最大值
  • 可能会让你更接近...df[df['column4'] == df.loc[df['column3'] == df['column3'].min(), 'column4'].max()]

标签: pandas dataframe


【解决方案1】:

另一种方法是groupby 2次:

minval=df.groupby(['column1','column2'])['column3'].min().tolist()
maxval=df.loc[df['column3'].isin(minval)].groupby(['column1','column2'])['column4'].max().tolist()
df['column6']=df['column5'].where(df['column4'].isin(maxval))

df的输出:

  column1 column2  column3  column4  column5  column6
0       A       B        5     4234      123      NaN
1       A       B        2      432     3243      NaN
2       A       B       10      123       43      NaN
3       A       B        1      123       45      NaN
4       A       B        1      124    23243      NaN
5       A       B        1      125      234      NaN
6       A       B        1      126       23     23.0

【讨论】:

    【解决方案2】:

    你可以尝试如下

    import pandas as pd
    
    df = pd.DataFrame({
        "column1":["A", "A", "A", "A", "A", "A", "A"],
        "column2":["B", "B", "B", "B", "B", "B", "B"],
        "column3":[5, 2, 10, 1, 1, 1, 1],
        "column4":[4234, 432, 123, 123, 124, 125, 126],
        "column5":[123, 3243, 43, 45, 23243, 234, 23]
    })
    
    df
    
        column1     column2     column3     column4     column5
    0   A              B          5            4234       123
    1   A              B          2            432        3243
    2   A              B          10           123        43
    3   A              B          1            123        45
    4   A              B          1            124        23243
    5   A              B          1            125        234
    6   A              B          1            126        23
    
    row_index = df.loc[df["column3"]==(df.groupby(["column1", "column2"])["column3"].min()).min()]["column4"].idxmax()
    val_index = df["column5"].iloc[(df.loc[df["column3"]==(df.groupby(["column1", "column2"])["column3"].min()).min()]["column4"].idxmax())]
    
    df.loc[row_index, "column6"] = val_index
    
    df
        column1     column2     column3     column4     column5     column6
    0   A               B           5       4234        123         NaN
    1   A               B           2       432         3243        NaN
    2   A               B           10      123         43          NaN
    3   A               B           1       123         45          NaN
    4   A               B           1       124         23243       NaN
    5   A               B           1       125         234         NaN
    6   A               B           1       126         23          23.0
    

    如果你想要它在一行中

    df.loc[df.loc[df["column3"]==(df.groupby(["column1", "column2"])["column3"].min()).min()]["column4"].idxmax(), "column6"] = df["column5"].iloc[(df.loc[df["column3"]==(df.groupby(["column1", "column2"])["column3"].min()).min()]["column4"].idxmax())]
    

    另一种选择

    df.loc[(df[df['column4'] == df.loc[df['column3'] == df['column3'].min(), 'column4'].max()]["column5"]).index, "column6"] = df[df['column4'] == df.loc[df['column3'] == df['column3'].min(), 'column4'].max()]["column5"]
    

    【讨论】:

      【解决方案3】:
      • 找到column3的最小值为df.loc[df["column3"].eq(df["column3"].min())]的行
      • 在这些行中找到最大为 column4 的行
      • 重命名并重新组合在一起
      import io
      import pandas as pd
      df = pd.read_csv(io.StringIO("""column1 | column2 | column3  |column4  | column5 
      A       |    B    |    5     |   4234  |   123   
      A       |    B    |    2     |   432   |   3243  
      A       |    B    |    10    |   123   |   43    
      A       |    B    |    1     |   123   |   45    
      A       |    B    |    1     |   124   |   23243 
      A       |    B    |    1     |   125   |   234   
      A       |    B    |    1     |   126   |   23   """), sep="|").pipe(lambda d: d.rename(columns={c:c.strip() for c in d.columns}))
      
      
      df.groupby(["column1", "column2"], as_index=False).apply(
          lambda df: df.join(
              df.loc[df["column3"].eq(df["column3"].min())]
              .loc[lambda d: d["column4"].eq(d["column4"].max()), "column5"]
              .rename("column6")
          )
      )
      
      column1 column2 column3 column4 column5 column6
      0 A B 5 4234 123 nan
      1 A B 2 432 3243 nan
      2 A B 10 123 43 nan
      3 A B 1 123 45 nan
      4 A B 1 124 23243 nan
      5 A B 1 125 234 nan
      6 A B 1 126 23 23

      【讨论】:

      • 认为 group by 在这里对于 column1 和 column2 是必要的,因为它总是会找到第 3 列的最小值等等,对吧?
      • 你的问题比刚开始的时候更明确了,是的。更新
      猜你喜欢
      • 2021-07-25
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 2014-02-04
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多