Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在groupby表上应用函数,该函数依赖于另一列的值并返回所有其他列_Python_Python 3.x_Pandas_Dataframe_Pandas Groupby - Fatal编程技术网

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()