同时选择最大值和最小值

2024-10-02 22:35:27 发布

您现在位置:Python中文网/ 问答频道 /正文

给出如下数据帧:

   count        date location  type
0    100  2018-01-01    site1  high
1     10  2018-01-01    site2   low
2     11  2018-01-01    site3   low
3    101  2018-01-03    site2  high
4    103  2018-01-03    site2  high
5     15  2018-01-03    site3   low

我需要找到每一天的最高和最低计数(在mm dd格式,年是无关的)。我想要的结果是这样的:

                count       date location
month-day type                           
01-01     high    100 2018-01-01    site1
          low      10 2018-01-01    site2
01-03     high    103 2018-01-03    site2
          low      15 2018-01-03    site3

我有个办法,但我肯定可以把它清理干净。以下是我目前掌握的情况:

df = pd.DataFrame({'date':['2018-01-01', '2018-01-01', '2018-01-01', '2018-01-03', '2018-01-03', '2018-01-03'],
                   'location':['site1', 'site2', 'site3', 'site2', 'site2', 'site3'], 
                   'type':['high', 'low', 'low', 'high', 'high', 'low'], 
                   'count':[100, 10, 11, 101, 103, 15]})

df['date'] = pd.to_datetime(df['date'])
df['month-day'] = df['date'].apply(lambda x: x.strftime('%m-%d')) 

maxCount = df.loc[df.groupby(['month-day']['type'=='high'])['count'].idxmax()]
minCount = df.loc[df.groupby(['month-day']['type'=='low'])['count'].idxmin()]

df = maxCount.merge(minCount, how='outer')
df.set_index(['month-day', 'type'], inplace=True)
df.sort_index(inplace=True)

这些最终将被用作matplotlib的输入,以图表计数与月日的高低,因此,将它们分开,而不是将它们重新连接在一起实际上可能是有意义的,但是有更好的方法来做到这一点吗?groupby对于][似乎特别不确定,但它确实有效。我唯一关心的是月日、类型和计数(类型只需要知道它是低还是高,所以如果我用一个专用的系列表示低,一个表示高,那么一旦我把月日和计数放入适当的系列中,就不需要保持类型)


Tags: 类型dfdatetypecountlocationlow计数
3条回答

你想做的是复杂的事实,你已经分配高点和低点。你需要解释这些吗(一天的最大值是否标记为low?) 如果没有,你可以做一些简单的事情:

df.groupby(['month-day']).agg({ 'count': ['min', 'max'] })                                                                                                                                         

这会给你这个:

          count     
            min  max
month-day           
01-01        10  100
01-03        15  103

你不是很清楚逻辑:是否应该包括type?根据你的尝试,我将假设是:

# groupby
group = df.groupby('month-day')['count']

# create your min and max logic for boolean indexing
min_log = ((df['count'] == group.transform(min)) & (df['type'] == 'low'))
max_log = ((df['count'] == group.transform(max)) & (df['type'] == 'high'))

# boolean indexing to filter df
df[ min_log | max_log]

        date location  type  count month-day
0 2018-01-01    site1  high    100     01-01
1 2018-01-01    site2   low     10     01-01
4 2018-01-03    site2  high    103     01-03
5 2018-01-03    site3   low     15     01-03

你可以试试aggstacklocset_index

s = pd.to_datetime(df.date).dt.strftime('%m-%d')
m = df.groupby(s)['count'].agg(['idxmax', 'idxmin']).stack()
df_out = df.loc[m].set_index([m.index.droplevel(1), 'type'])

Out[127]:
                  date location  count
date  type
01-01 high  2018-01-01    site1    100
      low   2018-01-01    site2     10
01-03 high  2018-01-03    site2    103
      low   2018-01-03    site3     15

相关问题 更多 >