【发布时间】:2016-08-05 13:34:21
【问题描述】:
我正在努力处理每小时降水数据,例如
index=pd.date_range('1/1/2011', periods=365*24, freq='H')
precipitation_indicator=np.random.randint(low=0, high=2, size=(365*24,))
precipitation_sum=np.random.ranf((365*24,))*6*precipitation_indicator
prec_dataH=pd.DataFrame(data={'prec_ind':precipitation_indicator, prec_sum':precipitation_sum},index=index)
如果在连续的时间点有降水,但如果在一个事件中存在一定长度的间隙,我想定义降雨事件。 我使用以下代码通过滚动窗口解决了这个问题
gap_to_ignore=1
prec_dataH['event_ind']=prec_dataH['prec_ind'].rolling(window=(1+2*gap_to_ignore), center=True).max().dropna()
通过这样做,每当有降水时,我会得到一个 event_ind 为 1 的事件,并且在雨事件中的 2 小时休息时间,以及在雨事件前 1 小时和雨事件后 1 小时的时间戳。我现在想提前 1 小时和雨后删除这个。我管理这个
1.) 为 event_ind 中发生的每个更改提供一个连续编号
prec_dataH['event_no'] = (prec_dataH['event_ind'].shift(1) != prec_dataH['event_ind']).astype(int).cumsum()
2.) 为 event_no 分配干燥期的 NaN 值
def reorder_eventNumbers_dryStart (event_numbers):
if event_numbers % 2 !=0:
return event_numbers/2
else:
return np.NaN
def reorder_eventNumbers_rainStart (event_numbers):
if event_numbers % 2 ==0:
return event_numbers/2
else:
return np.NaN
if prec_dataH.ix[1, 'event_ind']==1.:
prec_dataH['event_no']=prec_dataH['event_no'].apply(reorder_eventNumbers_rainStart)
elif prec_dataH.ix[1, 'event_ind']==0.:
prec_dataH['event_no']=prec_dataH['event_no'].apply(reorder_eventNumbers_dryStart)
3.) 按 event_no 分组,遍历组并将 NaN 值分配给提前 1 小时和降水事件后 1 小时的值,最后将组连接到新的 DataFrame。
这是相当耗时的,因此会发生 SettingWighCopyWarning,我不明白为什么会发生这种情况。
A value is trying to be set on a copy of a slice from a DataFrame.
这是我使用的代码:
rainEvents=prec_dataH.groupby('event_no')
groups=[]
for name, group in rainEvents:
group.ix[0:gap_to_ignore,'event_ind'] =np.NaN
group.ix[0:gap_to_ignore,'event_no'] =np.NaN
group.ix[-gap_to_ignore:, 'event_ind']=np.NaN
group.ix[-gap_to_ignore:,'event_no'] =np.NaN
groups.append(group)
rainEvents_corrected=pd.concat(groups)
那么如何避免这种 SettingWithCopyWarning 以及如何让我的代码更高效??
提前致谢, 阿克塞尔
【问题讨论】:
-
将
group = group.copy()添加为for循环的第一行。这摆脱了SettingWithCopyWarning并加快了您的计算速度。 -
感谢您的回答,这大大加快了计算速度。但是有没有更好的方法从 groupby 对象中取出 DataFrame 或应用过滤器而不是 for 循环?