繁体   English   中英

基于 Pandas 条件的行的最大值和最小值(取决于列名)

[英]Max & Min for the rows based on conditions in Pandas (column name dependent)

我有一个 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开头的列链接。

我想要的是

  1. 确定所有具有 `strt' 的列中最大的列,即 Astrt、Bstrt、Xstrt 和 Ystrt,并放入一个新列 'Tsrt'
  2. 然后是新列“趋势”中相应的“结束”值。 因此,例如,如果 'Bstrt' 是最大的,则 'Bend'(是否最大无关紧要)进入列 'Tend'
  3. 正如我所说,以A开头的列与以X开头的列链接,以B开头的列与以Y开头的列链接。 所以 2 个新列 'Ustrt' 和 '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

希望,我想做什么很清楚。 有人可以帮忙吗? 谢谢。

使用filterlookupreplace来构造这些列:

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)

不知道如何在 Stack Overflow 中正确粘贴宽数据帧:

    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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM