Python 在groupby表上应用函数,该函数依赖于另一列的值并返回所有其他列
我有一个数据框Python 在groupby表上应用函数,该函数依赖于另一列的值并返回所有其他列,python,python-3.x,pandas,dataframe,pandas-groupby,Python,Python 3.x,Pandas,Dataframe,Pandas Groupby,我有一个数据框df,它的行基本上是给定时间date(每天,每个站点有一个记录高和一个记录低)的给定站点ID的记录温度T。列MinMax告诉我它是创纪录的高还是创纪录的低。看起来是这样的: df Date ID MinMax T 0 01-01-2020 UH24GT2 MAX 13.4 1 02-01-2020 UJ24GT1 MIN -23.5 2 02-06-2020 UK21GT4
df
,它的行基本上是给定时间date
(每天,每个站点有一个记录高和一个记录低)的给定站点ID
的记录温度T
。列MinMax
告诉我它是创纪录的高还是创纪录的低。看起来是这样的:
df
Date ID MinMax T
0 01-01-2020 UH24GT2 MAX 13.4
1 02-01-2020 UJ24GT1 MIN -23.5
2 02-06-2020 UK21GT4 MAX 38.5
3 15-07-2020 JK32HT6 MAX 43.1
我想按日期对这些温度进行分组,并为每个日期提取最高记录高温和最低记录低温及其相关观测站。预期结果如下:
df_min_max
date ID MIN T MIN ID MAX T MAX
0 01-01-2020 HT21GT2 -28.4 JK21HT2 43.4
1 02-01-2020 UI24GT3 -31.2 UJ23HJ5 40.8
2 03-01-2020 JK21HT4 -30.3 JH12TH4 38.5
3 04-01-2020 BE12HT6 -29.8 JK34UT5 43.1
(请注意,我不太关心是否有几个站点ID具有相同的记录高或记录低。只有其中一个站点的ID就足够了)
我尝试通过创建一个自定义函数min\u或\u max
来实现这一点,该函数应用于分组数据帧(按日期),并在“sub”组上进行迭代-从MinMax
上的第二个groupby构造的数据帧,以知道它是否应该使用min或max。这还返回传递的数据帧的索引,以便我可以返回到它并查找最大或最小项的ID
def min_or_max(dS):
for name, group in dS.groupby(['MinMax']):
if(name == 'TMAX'):
maxT = group['T'].max()
IDmax = group['T'].idxmax()
else:
minT = group['T'].min()
IDmin = group['T'].idxmin()
return pd.Series({'ID max':IDmax, 'maxT':maxT, 'ID min':IDmin, 'minT':minT})
df_min_max = df[['Date','MinMax','T','ID']].groupby(['Date']).apply(lambda x: min_or_max(x))
df_min_max['ID max'] = df['ID'].iloc[df_min_max['ID max'].values].values
df_min_max['ID min'] = df['ID'].iloc[df_min_max['ID min'].values].values
事实是,这是有效的。但是它相当长。而且,即使我一个月前才开始使用Python,我还是觉得这是一种非常奇怪的方式。。。因此,我想知道是否有一种更快/更聪明的方法可以做到这一点。您可以首先通过
MAX
行过滤行,并与MAX
一起使用,因为ID
转换为索引,类似于min
和idxmin
,最后通过以下方式连接在一起:
如果需要使用和处理多个列:
如果除了要保留的ID之外还有多个列,那么这是否也可行?(要将所有这些列放入索引中,请执行groupby和aggregate,然后重置_index)@mwoua-It工作,但在
ID MIN中,ID MAX
得到了类似('UH24GT2','val')
的元组。所以添加了另一个解决方案。我想应该是('ID MAX','idxmax'),('T MAX','MAX')
而不是('ID MAX','MAX'),('T MAX','idxmax')
,否则,当我只有4列时,这正是我所期望的。稍后我将针对多个专栏测试您的第二个建议。谢谢@对不起,你是对的。
m = df['MinMax'].eq('MAX')
df1 = (df[m].set_index('ID')
.groupby('Date')['T']
.agg([('ID MAX', 'idxmax'),('T MAX','max')]))
df2 = (df[~m].set_index('ID')
.groupby('Date')['T']
.agg([('ID MIN', 'idxmin'),('T MIN','min')]))
df_min_max = pd.concat([df1, df2], axis=1).reset_index()
df1 = (df[m].drop('MinMax', axis=1)
.sort_values(['Date', 'T'], ascending=[True, False])
.drop_duplicates('Date')
.set_index('Date')
.add_suffix(' MAX'))
df2 = (df[~m].drop('MinMax', axis=1)
.sort_values(['Date', 'T'])
.drop_duplicates('Date')
.set_index('Date')
.add_suffix(' MIN'))
df_min_max = pd.concat([df1, df2], axis=1).reset_index()