我试图用pandas
0.13.1来减少气象数据。我有一个很大的浮动数据帧。多亏了this answer我最有效地将数据分组为半小时的间隔。我使用groupby
+apply
而不是{
>>> winddata
sonic_Ux sonic_Uy sonic_Uz
TIMESTAMP
2014-04-30 14:13:12.300000 0.322444 2.530129 0.347921
2014-04-30 14:13:12.400000 0.357793 2.571811 0.360840
2014-04-30 14:13:12.500000 0.469529 2.400510 0.193011
2014-04-30 14:13:12.600000 0.298787 2.212599 0.404752
2014-04-30 14:13:12.700000 0.259310 2.054919 0.066324
2014-04-30 14:13:12.800000 0.342952 1.962965 0.070500
2014-04-30 14:13:12.900000 0.434589 2.210533 -0.010147
... ... ...
[4361447 rows x 3 columns]
>>> winddata.dtypes
sonic_Ux float64
sonic_Uy float64
sonic_Uz float64
dtype: object
>>> hhdata = winddata.groupby(TimeGrouper('30T')); hhdata
<pandas.core.groupby.DataFrameGroupBy object at 0xb440790c>
我想在'Ux/Uy'列上使用math.atan2
,但在成功地apply
任何函数时都遇到了问题。我得到关于属性ndim
的回溯:
我可以很好地遍历groupby对象。我也可以将结果包装成Series
或DataFrame
,但包装值需要添加一个索引,该索引与我的原始索引元组。按照this answer的建议删除重复索引没有按预期工作。因为我可以从这个问题中重现问题和解决方案,所以我想知道是否因为我在分组一个DateTimeIndex一个索引,所以是否认为它的行为不同。在
>>> for name, g in hhdata:
... print name, atan2(g['sonic_Ux'].mean(), g['sonic_Uy'].mean()), ' wd'
...
2014-04-30 14:00:00 0.13861912975 wd
2014-04-30 14:30:00 0.511709085506 wd
2014-04-30 15:00:00 -1.5088990774 wd
2014-04-30 15:30:00 0.13200013186 wd
<<snip>>
>>> def winddir(g):
... return pd.Series(atan2( np.mean(g['sonic_Ux']), np.mean(g['sonic_Uy']) ), name='wd')
...
>>> hhdata.apply(winddir)
2014-04-30 14:00:00 0 0.138619
2014-04-30 14:30:00 0 0.511709
2014-04-30 15:00:00 0 -1.508899
2014-04-30 15:30:00 0 0.132000
...
2014-05-05 14:00:00 0 -2.551593
2014-05-05 14:30:00 0 -2.523250
2014-05-05 15:00:00 0 -2.698828
Name: wd, Length: 243, dtype: float64
>>> hhdata.apply(winddir).index[0]
(Timestamp('2014-04-30 14:00:00', tz=None), 0)
>>> def winddir(g):
... return pd.DataFrame({'wd':atan2(g['sonic_Ux'].mean(), g['sonic_Uy'].mean())}, index=[g.name])
...
>>> hhdata.apply(winddir)
wd
2014-04-30 14:00:00 2014-04-30 14:00:00 0.138619
2014-04-30 14:30:00 2014-04-30 14:30:00 0.511709
2014-04-30 15:00:00 2014-04-30 15:00:00 -1.508899
2014-04-30 15:30:00 2014-04-30 15:30:00 0.132000
...
[243 rows x 1 columns]
>>> hhdata.apply(winddir).index[0]
(Timestamp('2014-04-30 14:00:00', tz=None), Timestamp('2014-04-30 14:00:00', tz=None))
>>>
>>> tsfast.groupby(TimeGrouper('30T')).apply(lambda g:
... Series({'wd': atan2(g.sonic_Ux.mean(), g.sonic_Uy.mean()),
... 'ws': np.sqrt(g.sonic_Ux.mean()**2 + g.sonic_Uy.mean()**2)}))
2014-04-30 14:00:00 wd 0.138619
ws 1.304311
2014-04-30 14:30:00 wd 0.511709
ws 0.143762
2014-04-30 15:00:00 wd -1.508899
ws 0.856643
...
2014-05-05 14:30:00 wd -2.523250
ws 3.317810
2014-05-05 15:00:00 wd -2.698828
ws 3.279520
Length: 486, dtype: float64
已编辑:在返回序列或数据帧时注意到额外的列吗?然后按照前面链接的答案公式得到一个层次索引?在
我最初的问题是:应该从我的apply
ed函数返回什么类型的值,以便groupby apply操作产生一个1列的数据帧或序列,其长度等于组的数目和用作索引值的组名(例如时间戳)?在
在反馈和进一步调查之后,我真正要问的是为什么在索引上分组与在列上分组的行为不同?观察将DatetimeIndex
更改为具有字符串值的列,以实现与TimeGrouper('30T')
相同的分组,结果是我预期的行为:
>>> winddata.index.name = 'WASINDEX'
>>> data2 = winddata.reset_index()
>>> def to_hh(x): # <-- big hammer
... ts = x.isoformat()
... return ts[:14] + ('30:00' if int(ts[14:16]) >= 30 else '00:00')
...
>>> data2['TS'] = data2['WASINDEX'].apply(lambda x: to_hh(x))
>>> wd = data2.groupby('TS').apply(lambda df: Series({'wd': np.arctan2(df.x.mean(), df.y.mean())}))
>>> type(wd)
pandas.core.frame.DataFrame
>>> wd.columns
Index([u'wd'], dtype=object)
>>> wd.index
Index([u'2014-04-30T14:00:00', u'2014-04-30T14:30:00', <<snip>> dtype=object)
在<;0.14.0中,使用pd.时间分配器在
^{pr2}$相关问题 更多 >
编程相关推荐