Python 在数据帧的列中满足条件且无重复计数条纹时跟踪3天条纹
我有一个由8个不同美国城市的气候观测数据组成的数据框架 我试图找出数据集中每个位置每年的热浪数量(连续3天,最高温度为90度或以上) 我将热浪定义为连续3天,但只有连续3天。例如:Python 在数据帧的列中满足条件且无重复计数条纹时跟踪3天条纹,python,pandas,numpy,Python,Pandas,Numpy,我有一个由8个不同美国城市的气候观测数据组成的数据框架 我试图找出数据集中每个位置每年的热浪数量(连续3天,最高温度为90度或以上) 我将热浪定义为连续3天,但只有连续3天。例如: If Aug. 8 hit 87 Aug. 9 hit 90 Aug. 10 hit 92 Aug. 11 hit 94 Aug. 12 hit 93 Aug. 13 hit 101 Aug. 14 hit 94 Aug. 15 hit 77 在“热浪”一栏中,8月9日和8
If Aug. 8 hit 87
Aug. 9 hit 90
Aug. 10 hit 92
Aug. 11 hit 94
Aug. 12 hit 93
Aug. 13 hit 101
Aug. 14 hit 94
Aug. 15 hit 77
在“热浪”一栏中,8月9日和8月12日的数值为“1”,反映了两个不同的3天周期,其中最大值达到90或以上
我目前的策略并没有在这样连续的日子里奏效
我一直在尝试使用np.where。首先,我要检查当天的温度是否达到90或以上。接下来,我会提前检查,看看在接下来的两天,最大值是否达到或超过90。最后,我检查了前两天的热浪列是否没有“1”。如果满足所有这些条件,则在行的“热浪”列中放置1
summer['Next90'] = summer.Max.shift(-1)
summer['Following90'] = summer.Max.shift(-2)
summer['HeatWave'] = 0
summer['HeatWave'] = np.where((summer['Next90']>=90) &
(summer['Max']>=90) & (summer['Following90']>=90) & (summer.shift(1)
['HeatWave']!=1) & (summer.shift(2)['HeatWave']!=1), 1, np.nan)
这个序列的问题是,我不认为np.where可以在“HeatWave”列在前一行中放置1(或np.nan)之后检查它。所以,我在热浪专栏中得到了很多“1”,但是序列最终被重复计算。我还使用iterrows在for循环中尝试了这一点,但也遇到了同样的困难。有人能提出更好的方法吗?这里是一种你可以尝试的方法(示例数据显示在文章末尾)
df = pd.read_csv('/path/to/file', sep='\s\s+', engine='python', parse_dates=['date'])
# N-day streak
N = 3
# if there are duplicates in the same date, drop them and keep the one with highest temp
df = df.sort_values(['date', 'temp'], ascending=[1,0]).drop_duplicates(subset=['date'])
# fix missing dates issue and fill missing 'temp' with 0
df = df.set_index('date').asfreq('D').reset_index().fillna(0)
print(df)
# date temp
#0 2018-08-01 83
#1 2018-08-02 99
#2 2018-08-03 99
#3 2018-08-04 87
#4 2018-08-05 90
#5 2018-08-06 92
#6 2018-08-07 0
#7 2018-08-08 92
#8 2018-08-09 90
#9 2018-08-10 92
#10 2018-08-11 94
#11 2018-08-12 93
#12 2018-08-13 101
#13 2018-08-14 94
#14 2018-08-15 77
# contition-1 df.temp >= 90
c1 = df.temp.ge(90)
# group label (each group forms a streak)
g = (c1 != c1.shift()).cumsum()
- cnt:行的总数
- n:cumcount()作为序列号
- g:这里加的只是参考,不用于以后的计算
df1 = df.assign( cnt=df.groupby(g).date.transform('count') , n=df.groupby(g).agg('cumcount') , g=g ) print(df1) # date temp cnt g n #0 2018-08-01 83 1 1 0 #1 2018-08-02 99 2 2 0 #2 2018-08-03 99 2 2 1 #3 2018-08-04 87 1 3 0 #4 2018-08-05 90 2 4 0 #5 2018-08-06 92 2 4 1 #6 2018-08-07 0 1 5 0 #7 2018-08-08 92 7 6 0 #8 2018-08-09 90 7 6 1 #9 2018-08-10 92 7 6 2 #10 2018-08-11 94 7 6 3 #11 2018-08-12 93 7 6 4 #12 2018-08-13 101 7 6 5 #13 2018-08-14 94 7 6 6 #14 2018-08-15 77 1 7 0
# condition-2: cnt >= N , a streak must have at least N rows
c2 = df1.cnt.ge(N)
# condition-3: (n%N)==0 and (n+N) <= cnt
# the last n%N==0 might not have enough dates for a N-day streak
c3 = df1.n.mod(N).eq(0) & df1.n.le(df1.cnt-N)
del(df1)
date temp
Aug 1, 2018 83
Aug 2, 2018 99
Aug 2, 2018 65
Aug 3, 2018 99
Aug 2, 2018 70
Aug 4, 2018 87
Aug 5, 2018 90
Aug 6, 2018 92
Aug 8, 2018 92
Aug 9, 2018 90
Aug 10, 2018 92
Aug 11, 2018 94
Aug 12, 2018 93
Aug 13, 2018 101
Aug 14, 2018 94
Aug 15, 2018 77
您希望从这些数据中得到什么?因此,基本上,我的数据框在连续三天的开始时,热浪列中会有一个“1”,最大值>=90。在至少2天过去之前,热浪列中不会有另一个“1”,不管接下来的2天是否也有一个最大值>=90(防止重复计算连续3天)。这绝对是太棒了(我说这个还没有测试过,但今晚我会这么做)。我非常感谢你花时间发送这个!工作出色!我甚至都说不出我有多么感谢你。下面是一个小代码片段:
climate[(climate['City']='DFW')&(climate['Year']==2015)和(climate['Max']>=90)]Out[13]:Max-Min-Avg。。。年月日。。。2015-05-18 91.0 68.0 79.5 ... 2015-05南0 2015-06-03 91.0 72.0 81.5。。。2015-06南1
@wnjl,我很高兴它对你有用。如果我的答案有帮助的话,你介意投我一票吗。享受一个美好的周末:-)我试过了,但还不能算我的得票:-(我想我太新了。
date temp
Aug 1, 2018 83
Aug 2, 2018 99
Aug 2, 2018 65
Aug 3, 2018 99
Aug 2, 2018 70
Aug 4, 2018 87
Aug 5, 2018 90
Aug 6, 2018 92
Aug 8, 2018 92
Aug 9, 2018 90
Aug 10, 2018 92
Aug 11, 2018 94
Aug 12, 2018 93
Aug 13, 2018 101
Aug 14, 2018 94
Aug 15, 2018 77