Python 如何在pandas中映射一个函数,将列中的每条记录与上一条记录和下一条记录进行比较
我有一个水位的时间序列,我需要计算几个任意洪水阶段的月度和年度统计数据。具体来说,我需要确定每月超过洪水水位的持续时间,以及这些偏移发生的次数。此外,由于数据记录器的噪音,我需要排除持续时间小于1小时的洪水以及事件间隔小于1小时的洪水 模型数据:Python 如何在pandas中映射一个函数,将列中的每条记录与上一条记录和下一条记录进行比较,python,pandas,Python,Pandas,我有一个水位的时间序列,我需要计算几个任意洪水阶段的月度和年度统计数据。具体来说,我需要确定每月超过洪水水位的持续时间,以及这些偏移发生的次数。此外,由于数据记录器的噪音,我需要排除持续时间小于1小时的洪水以及事件间隔小于1小时的洪水 模型数据: start = datetime.datetime(2014,9,5,12,00) daterange = pd.date_range(start, periods = 10000, freq = '30min', name = "Datetime")
start = datetime.datetime(2014,9,5,12,00)
daterange = pd.date_range(start, periods = 10000, freq = '30min', name = "Datetime")
data = np.random.random_sample((len(daterange), 3)) * 10
columns = ["Pond_A", "Pond_B", "Pond_C"]
df = pd.DataFrame(data = data, index = daterange, columns = columns)
flood_stages = [('Stage_1', 4.0), ('Stage_2', 6.0)]
我期望的输出是:
Pond_A_Stage_1_duration Pond_A_Stage_1_events \
2014-09-30 12:00:00 35.5 2
2014-10-31 12:00:00 40.5 31
2014-11-30 12:00:00 100 16
2014-12-31 12:00:00 36 12
各水库各洪水期的持续时间和事件
我试着按月分组,遍历池塘,然后遍历每一行,如下所示:
grouper = pd.TimeGrouper(freq = "1MS")
month_groups = df.groupby(grouper)
for name, group in month_groups:
flood_stage_a = group.sum()[1]
flood_stage_b = group.sum()[2]
inundation_a = False
inundation_30_a = False
inundation_hour_a = False
change_inundation_a = 0
for level in group.values:
if level[1]:
inundation_a = True
else:
inundation_a = False
if inundation_hour_a == False and inundation_a == True and inundation_30_a == True:
change_inundation_a += 1
inundation_hour_a = inundation_30_a
inundation_30_a = inundation_a
但这是一个穴居人的解决方案,而启发式算法变得混乱,因为如果洪水在一个月内开始并持续到下一个月,我不想计算新的事件。这也不包括从开始到结束不到一小时的事件。有没有更好的方法将记录与上一个记录和下一个记录进行比较
我的另一个想法是用序列移位的t+1、t+2、t-1、t-2创建新列,这样我可以对每一行计算一次,但这似乎仍然效率低下。有没有更聪明的方法通过映射函数来实现这一点?让我给出一个快速、部分的答案,因为目前还没有人回答,如果这还不足以满足您的要求,也许其他人以后可以做得更好 你可以很容易地计算洪水水位以上的时间。我除以48,所以单位是天
df[ df > 4 ].groupby(pd.TimeGrouper( freq = "1MS" )).count() / 48
Pond_A Pond_B Pond_C
Datetime
2014-09-01 15.375000 15.437500 14.895833
2014-10-01 18.895833 18.187500 18.645833
2014-11-01 17.937500 17.979167 18.666667
2014-12-01 18.104167 18.354167 18.958333
2015-01-01 18.791667 18.645833 18.708333
2015-02-01 16.583333 17.208333 16.895833
2015-03-01 18.458333 18.458333 18.458333
2015-04-01 0.458333 0.520833 0.500000
计算不同的事件有点困难,但像这样的事情会让你得到大部分的方法。(请注意,这会产生大量不切实际的洪水事件,但这只是因为样本数据是如何设置的,而不是典型池塘的反映,尽管我不是池塘洪水方面的专家!)
如果您共享您正在工作的数据表以及所需的输出,这将有所帮助!谢谢你,我知道熊猫有一个聪明的方法来做到这一点,但我真的是在风中扭曲试图解决它。
for c in df.columns:
df[c+'_events'] = ((df[c] > 4) & (df[c].shift() <= 4))
df.iloc[:,-3:].groupby(pd.TimeGrouper( freq = "1MS" )).sum()
Pond_A_events Pond_B_events Pond_C_events
Datetime
2014-09-01 306 291 298
2014-10-01 381 343 373
2014-11-01 350 346 357
2014-12-01 359 352 361
2015-01-01 355 335 352
2015-02-01 292 337 316
2015-03-01 344 360 386
2015-04-01 9 10 9
df[c+'_events'] = ((df[c] > 4) & (df[c].shift(1) <= 4) &
(df[c].shift(-1) > 4) & (df[c].shift(2) <= 4))
Pond_A_events Pond_B_events Pond_C_events
Datetime
2014-09-01 70 71 72
2014-10-01 91 85 81
2014-11-01 87 75 91
2014-12-01 88 87 77
2015-01-01 91 95 94
2015-02-01 79 90 83
2015-03-01 83 78 85
2015-04-01 0 2 2