Groupby 名称用所有列中的最大值替换值 pandas
Posted
技术标签:
【中文标题】Groupby 名称用所有列中的最大值替换值 pandas【英文标题】:Groupby names replace values with there max value in all columns 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
用最大值替换所有值。我们从val1
和val2
中选择最大值
如果我这样做,我将只从 val1
获得最大值
df["val1"] = df.groupby("name1")["val1"].transform("max")
【问题讨论】:
name2 不应该是字符串而不是数字吗? 您的 BBB 输入的 val2 为 12 和 15 - 为什么您的输出有 31 和 15? @HenryYik 我的错误编辑了它 为什么有 2 组列(name1
和 name2
和 val1
和 val2
)?为什么不能有一个 name
列和一个 val
列,有充分的理由吗?
@JonClements BBB val1 和 val2 的最大值为 22,因此将所有 BBB 替换为 22
【参考方案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"firstlast" 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'ij' 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
【讨论】:
以上是关于Groupby 名称用所有列中的最大值替换值 pandas的主要内容,如果未能解决你的问题,请参考以下文章
Python pandas:替换 groupby 对象中的选择值