给出这样的数据框:
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似乎对][
不太满意,但是它确实起作用。我唯一关心的是月日,类型和计数(并且只需要知道类型是低还是高,因此,如果我使用一个专门的序列来表示低和高,那么我就不需要保留输入一次,然后按月输入日期并按适当的顺序计数)。
答案 0 :(得分:1)
由于您已经分配了高点和低点,因此想要做的事情变得很复杂。您需要考虑这些吗? (一天的最大值标记为low
吗?)
如果没有,您可以使用以下简单的方法:
df.groupby(['month-day']).agg({ 'count': ['min', 'max'] })
哪个会给你这个:
count
min max
month-day
01-01 10 100
01-03 15 103
答案 1 :(得分:0)
您不清楚逻辑是否正确:应该包含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
答案 2 :(得分:0)
您可以尝试agg
,stack
,loc
和set_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