Python 马克斯;基于Pandas中的条件的行的最小值(取决于列名)

Python 马克斯;基于Pandas中的条件的行的最小值(取决于列名),python,pandas,dataframe,Python,Pandas,Dataframe,我有一个df如下 Astrt Aend Bstrt Bend Xstrt Xend Ystrt Yend 25 27 15 16 11 12 40 42 50 51 45 46 23 25 35 36 14 15 21 20 8 9 2 3 11

我有一个df如下

Astrt   Aend    Bstrt   Bend    Xstrt   Xend    Ystrt   Yend
25        27    15        16    11        12    40      42
50        51    45        46    23        25    35      36
14        15    21        20    8          9    2        3
11        11    45        49    46        47    12       13
在此df中,以
A
开头的列与以
X
开头的列链接,以
B
开头的列与以
Y
开头的列链接

我想要的是

  • 确定所有具有“strt”的列中最大的列,即Astrt、Bstrt、Xstrt和Ystrt,并将其放入新列“Tsrt”
  • 然后在新列“Tend”中输入相应的“end”值。因此,例如,如果is'Bstrt'是最大的,那么'Bend'(不管它是否是最大的)将进入'Tend'列
  • 正如我所说,以
    A
    开头的列与以
    X
    开头的列链接,以
    B
    开头的列与以
    Y
    开头的列链接。因此,两个新列“USTR”和“Uend”应分别填入各列的起始值和结束值 例如,如果“Xstrt”是最大的,那么“Ustrt”和“Uend”列将包含来自“Astrt”和“Aend”的值(无需分析,只需直接分析值)
  • 因此,基本上,我们需要找到所有具有“strt”的列的最大值,确定该列的名称,并根据其关系复制值

    上述df的预期结果如下所示

    Astrt   Aend    Bstrt   Bend    Xstrt   Xend    Ystrt   Yend    Tstrt   Tend    Ustrt   Uend
    25        27       15   16         11   12         40   42        40    42         15   16
    50        51       45   46         23   25         35   36        50    51         23   25
    14        15       21   20          8   9           2   3         21    20          2   3
    11        11       45   49         46   47         12   13        46    47         11   11
    
    希望我能清楚地知道我想做什么。
    有人能帮忙吗?谢谢。

    使用
    过滤器
    查找
    替换
    来构造这些列:

    df_strt = df.filter(regex='strt$')
    df_end = df.filter(regex='end$')
    s = df_strt.idxmax(1)
    d = {"X":"A", "A":"X", "Y":"B", "B":"Y"}
    df['Tstrt'] = df_strt.lookup(*zip(*s.items()))
    df['Tend'] = df_end.lookup(*zip(*s.str.replace('strt', 'end').items()))
    df['Ustrt'] = df_strt.lookup(*zip(*s.replace(d,regex=True).items()))
    df['Uend'] = (df_end.lookup(*zip(*s.str.replace('strt', 'end')
                                           .replace(d,regex=True).items())))
    
    Out[202]:
       Astrt  Aend  Bstrt  Bend  Xstrt  Xend  Ystrt  Yend  Tstrt  Tend  Ustrt  Uend
    0     25    27     15    16     11    12     40    42     40    42     15    16
    1     50    51     45    46     23    25     35    36     50    51     23    25
    2     14    15     21    20      8     9      2     3     21    20      2     3
    3     11    11     45    49     46    47     12    13     46    47     11    11
    

    多亏了@Andy.L和@Henry Yik,我找到了实现我想要的目标的另一种方法。把它放在这里只是为了文档

    a = df.filter(like='strt').idxmax(axis=1).str[0]
    d = {"X":"A", "A":"X", "Y":"B", "B":"Y"}
    df['Tstrt'] = df.filter(like='strt').max(axis=1)
    df['Tend']=df.lookup(df.index,a+'end')
    df['Ustrt']=df.lookup(df.index,a.map(d)+'strt')
    df['Uend']=df.lookup(df.index,a.map(d)+'end')
    df
    
    
    Astrt   Aend    Bstrt   Bend    Xstrt   Xend    Ystrt   Yend    Tstrt   Tend    Ustrt   Uend
    25       27     15       16     11       12     40        42       40      42   15      16
    50       51     45       46     23       25     35        36       50      51   23      25
    14       15     21       20     8         9     2          3       21      20   2       3
    11       11     45       49     46       47     12        13       46      47   11      11
    
    另一个解决方案:

    # create temporary dataframes for start and end
    strt = df.filter(regex=".strt$")
    end = df.filter(regex=".end$")
    
    Tstrt = strt.max(1).array    
    cond = strt.isin(Tstrt)
    cond = cond.to_numpy()
    Tend = end.to_numpy()[cond]
    
    # reshape boolean array based on positions (A replaces X, B replaces Y and vice versa)
    Ustrt = strt.to_numpy()[cond[:, [2, 3, 0, 1]]]
    Uend = end.to_numpy()[cond[:, [2, 3, 0, 1]]]
    
    df.assign(Tstrt=Tstrt, Tend=Tend, Ustrt=Ustrt, Uend=Uend)
    
    不知道如何在堆栈溢出中正确粘贴宽数据帧:

        Astrt   Aend    Bstrt   Bend    Xstrt   Xend    Ystrt   Yend    Tstrt   Tend    Ustrt   Uend
    0   25     27      15      16      11      12      40      42     40       42   15  16
    1   50     51      45      46      23      25      35      36     50       51   23  25
    2   14     15      21      20      8       9       2       3      21       20   2   3
    3   11     11      45      49      46      47      12     13      46       47   11  11