根据确切日期按季节分组数据

Posted

技术标签:

【中文标题】根据确切日期按季节分组数据【英文标题】:group data by season according to the exact dates 【发布时间】:2017-11-15 12:53:04 【问题描述】:

我有一个包含 4 年数据的 csv 文件,我正在尝试对 4 年内每个季节的数据进行分组,换句话说,我需要将我的整个数据汇总并绘制成 4 个季节。 这是我的数据文件:

timestamp,heure,lat,lon,impact,type
2006-01-01 00:00:00,13:58:43,33.837,-9.205,10.3,1
2006-01-02 00:00:00,00:07:28,34.5293,-10.2384,17.7,1
2007-02-01 00:00:00,23:01:03,35.0617,-1.435,-17.1,2
2007-02-02 00:00:00,01:14:29,36.5685,0.9043,36.8,1
2008-01-01 00:00:00,05:03:51,34.1919,-12.5061,-48.9,1
2008-01-02 00:00:00,05:03:51,34.1919,-12.5061,-48.9,1
....
2011-12-31 00:00:00,05:03:51,34.1919,-12.5061,-48.9,1

这是我想要的输出:

winter     (the mean value of impacts)
summer     (the mean value of impacts)
autumn      ....
spring      .....

其实我已经试过这段代码了:

names =["timestamp","heure","lat","lon","impact","type"]
data = pd.read_csv('flash.txt',names=names, parse_dates=['timestamp'],index_col=['timestamp'], dayfirst=True)

spring = range(80, 172)
summer = range(172, 264)
fall = range(264, 355)

def season(x):
    if x in spring:
       return 'Spring'
    if x in summer:
       return 'Summer'
    if x in fall:
       return 'Fall'
   else :
       return 'Winter'

 data['SEASON'] = data.index.to_series().dt.month.map(lambda x : season(x))
 data['impact'] = data['impact'].abs()
 seasonly = data.groupby('SEASON')['impact'].mean()

我得到了这个可怕的结果:

我错在哪里了?

【问题讨论】:

【参考方案1】:

你需要DatetimeIndex.dayofyear:

data['SEASON'] = data.index.dayofyear.map(season)

pandas.cut 的另一个解决方案:

bins = [0, 91, 183, 275, 366]
labels=['Winter', 'Spring', 'Summer', 'Fall']
doy = data.index.dayofyear
data['SEASON1'] = pd.cut(doy + 11 - 366*(doy > 355), bins=bins, labels=labels)

【讨论】:

【参考方案2】:

pandas.cut为了妥善处理 'Winter' 在年初和年末的情况,我将 dayofyear 移动了 11 并取了结果以 366 为模。我不使用与下面的 numpy 解决方案相同的技术的原因是 pd.cut 返回一个分类类型,我最终会得到 5 个类别,其中两个类别具有相同的标签。然后我可以将结果转换为字符串,但这感觉很草率。

data['SEASON'] = pd.cut(
    (data.index.dayofyear + 11) % 366,
    [0, 91, 183, 275, 366],
    labels=['Winter', 'Spring', 'Summer', 'Fall']
)

numpy.searchsorted为了妥善处理 'Winter' 在年初和年末的情况,我允许 'Winter' 使用两个垃圾箱

seasons = np.array(['Winter', 'Spring', 'Summer', 'Fall', 'Winter'])
f = np.searchsorted([80, 172, 264, 355], data.index.dayofyear)
data['SEASON'] = seasons[f]

plot

data.groupby('SEASON')['impact'].mean().plot.bar()

【讨论】:

我照你说的做了,我得到了这个错误:'numpy.ndarray'对象没有属性'values' @MarieAntoinette 我忘记您使用的是旧版本的pandas...稍后会更新...现在试试吧。 哈哈哦,是的,你还记得,非常感谢你的编辑,它现在正在工作【参考方案3】:

看起来像:

data['SEASON'] = data.index.to_series().dt.**month**.map(lambda x : season(x))

使用的月份大概是 1-12 或 0-11,它们都是“冬天”。 您需要使用一年中的某一天。

但是,如果您没有将一天的提取锁定在单行中,您可能会更容易看到这一点,并且可以打印以自己检查。只是说说而已。

【讨论】:

是的,你说得对,我只是打印检查,他们都是冬天,我怎么能像你说的那样写一年中的哪一天?

以上是关于根据确切日期按季节分组数据的主要内容,如果未能解决你的问题,请参考以下文章

sqlite-按日期分组,根据日期查询详细内容

如何根据每周日期创建移动平均线,按data.table中的多列分组?

Mongodb:按元素分组并根据条件显示子文档计数并按日期对文档进行排序

选择日期范围,根据关闭条件计算范围内的多条记录,按班次分组

Oracle - 按类别分组,日期范围[重复]

Pandas 每年按季节高效分组