首页 > 解决方案 > Groupby 在有条件的列中返回不同的结果?

问题描述

我有下面的数据框:

     equipment      value      loc
0       ac1         43.2       acs_blg
1       ac2         23.1       acs_blg
2       ac3         0.0        acs_blg
3       ac4         44.4       acs_blg
4       kz1         12.1       qet_blg
5       kz2         87.2       qet_blg
6       kz3         65.3       qet_blg
7       yy1         0.0        cna_blg
8       yy2         0.0        cna_blg
9       yy3         0.0        cna_blg
10      yy4         0.0        cna_blg
11      yy5         0.0        cna_blg
12      uu1         55.3       ppp_blg
13      uu2         0.0        ppp_blg
14      ta1         24.3       lck_blg
15      ta2         22.0       lck_blg
16      ta3         21.0       lck_blg

我想根据 3 个条件返回一个字符串:

  1. 如果 loc 中的所有设备的值都大于 > 0.0,则返回 'Online'
  2. 如果 loc 中的一个或多个设备具有 0.0 值,则返回 'Check'
  3. 如果一个 loc 中的所有设备都有 0.0 值,则返回 'Offline'

最终结果

     loc        status
0    acs_blg    Check
1    qet_blg    Online
2    cna_blg    Offline
3    ppp_blg    Check
4    lck_blg    Online

最好的解决方法是什么?

标签: pandasdataframepandas-groupby

解决方案


0通过with比较值Series.eq,然后使用GroupBy.alland GroupBy.any测试是否所有 ar 至少有一个匹配,最后通过以下方式创建新列numpy.select

mask = df['value'].eq(0)

df1 = mask.groupby(df['loc'], sort=False).agg(['any','all']).reset_index()

arr = np.select([df1['any'] & df1['all'], df1['any'], ~df1['any'] & ~df1['all']], 
                ['Offline','Check','Online'])

df2 = df1[['loc']].assign(status=arr)
print (df2)
       loc   status
0  acs_blg    Check
1  qet_blg   Online
2  cna_blg  Offline
3  ppp_blg    Check
4  lck_blg   Online

另一个想法是对列求和并比较是否相等10或者2

mask = df['value'].eq(0)

df1 = mask.groupby(df['loc'], sort=False).agg(['any','all']).reset_index()
print (df1)
       loc    any    all
0  acs_blg   True  False
1  qet_blg  False  False
2  cna_blg   True   True
3  ppp_blg   True  False
4  lck_blg  False  False

s = df1['any'].add(df1['all'].astype(int))
print (s)
0    1
1    0
2    2
3    1
4    0
dtype: int32

arr = np.select([s.eq(2), s.eq(1), s.eq(0)], ['Offline','Check','Online'])

df2 = df1[['loc']].assign(status=arr)
print (df2)
       loc   status
0  acs_blg    Check
1  qet_blg   Online
2  cna_blg  Offline
3  ppp_blg    Check
4  lck_blg   Online

推荐阅读