【问题标题】:Groupby names replace values with there max value in all columns pandasGroupby 名称用所有列中的最大值替换值 pandas
【发布时间】:2020-12-03 14:42:15
【问题描述】:

我有这个数据框

lst = [['AAA',15,'BBB',20],['BBB',16,'AAA',12],['BBB',22,'CCC',15],['CCC',11,'AAA',31],['DDD',25,'EEE',35]]
df = pd.DataFrame(lst,columns = ['name1','val1','name2','val2'])

看起来像这样

 name1   val1 name2 val2
0  AAA     15  BBB   20
1  BBB     16  AAA   12
2  BBB     22  CCC   15
3  CCC     11  AAA   31
4  DDD     25  EEE   35

我想要这个

 name1   val1 name2  val2
0  AAA     31  BBB    22
1  BBB     22  AAA    31
2  BBB     22  CCC    15
3  CCC     15  AAA    31
4  DDD     25  EEE    35

用最大值替换所有值。我们从val1val2中选择最大值

如果我这样做,我将只从 val1 获得最大值

df["val1"] = df.groupby("name1")["val1"].transform("max")

【问题讨论】:

  • name2 不应该是字符串而不是数字吗?
  • 您的 BBB 输入的 val2 为 12 和 15 - 为什么您的输出有 31 和 15?
  • @HenryYik 我的错误编辑了它
  • 为什么有 2 组列(name1name2val1val2)?为什么不能有一个 name 列和一个 val 列,有充分的理由吗?
  • @JonClements BBB val1 和 val2 的最大值为 22,因此将所有 BBB 替换为 22

标签: python python-3.x pandas pandas-groupby


【解决方案1】:

这是基于@ScottBoston 的回答:

res = pd.wide_to_long(df.reset_index(), ["name", "val"], "index", j="num")
res.update(res.groupby(["name"]).val.transform("max"))
res = res.unstack()
res.columns = [f"{first}{last}" for first, last in res.columns]
res.rename_axis(index=None)


   name1    name2   val1    val2
0   AAA     BBB     31      22
1   BBB     AAA     22      31
2   BBB     CCC     22      15
3   CCC     AAA     15      31
4   DDD     EEE     25      35

【讨论】:

    【解决方案2】:

    您可以使用lreshape(未记录且不确定是否已测试或将继续保留)获取长数据帧,然后使用最大值映射每对列。

    names = df.columns[df.columns.str.startswith('name')]
    vals = df.columns[df.columns.str.startswith('val')]
    
    s = (pd.lreshape(df, groups={'name': names, 'val': vals})
           .groupby('name')['val'].max())
    
    for n in names:
        df[n.replace('name', 'val')] = df[n].map(s)
    

      name1  val1 name2  val2
    0   AAA    31   BBB    22
    1   BBB    22   AAA    31
    2   BBB    22   CCC    15
    3   CCC    15   AAA    31
    4   DDD    25   EEE    35
    

    【讨论】:

      【解决方案3】:

      借用 Scott 的设置

      df_long = pd.wide_to_long(df.reset_index(), ['name','val'], 'index', j='num',sep='',suffix='\d+')
      d = df_long.groupby('name')['val'].max()
      
      df.loc[:,df.columns.str.startswith('val')]=df.loc[:,df.columns.str.startswith('name')].replace(d).values
      df
      Out[196]: 
        name1  val1 name2  val2
      0   AAA    31   BBB    22
      1   BBB    22   AAA    31
      2   BBB    22   CCC    15
      3   CCC    15   AAA    31
      4   DDD    25   EEE    35
      

      【讨论】:

        【解决方案4】:

        尝试使用pd.wide_to_long 将该数据框融合成一个长格式,然后使用 groupby 和 transform 来找到最大值。将该最大值映射到“名称”并重新整形为四列(宽)数据框:

        df_long = pd.wide_to_long(df.reset_index(), ['name','val'], 'index', j='num',sep='',suffix='\d+')
        mapper= df_long.groupby('name')['val'].max()
        df_long['val'] = df_long['name'].map(mapper)
        df_new = df_long.unstack()
        df_new.columns = [f'{i}{j}' for i,j in df_new.columns]
        df_new
        

        输出:

              name1 name2  val1  val2
        index                        
        0       AAA   BBB    31    22
        1       BBB   AAA    22    31
        2       BBB   CCC    22    15
        3       CCC   AAA    15    31
        4       DDD   EEE    25    35
        

        【讨论】:

          猜你喜欢
          • 2022-10-14
          • 2021-03-08
          • 2022-12-11
          • 2022-06-13
          • 1970-01-01
          • 1970-01-01
          • 2019-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多