html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,performed_via_github_app,issue https://github.com/pydata/xarray/issues/3896#issuecomment-605456013,https://api.github.com/repos/pydata/xarray/issues/3896,605456013,MDEyOklzc3VlQ29tbWVudDYwNTQ1NjAxMw==,9312831,2020-03-28T14:39:06Z,2020-03-28T14:39:06Z,NONE,">Minor comment / nit: you don't really need the astype(np.float), the result should already be of dtype float since there are missing values after the rolling sum. You're right. That is used for debuging the intermediate results. Thanks again @keewis @max-sixty. ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-605446570,https://api.github.com/repos/pydata/xarray/issues/3896,605446570,MDEyOklzc3VlQ29tbWVudDYwNTQ0NjU3MA==,14808389,2020-03-28T13:19:46Z,2020-03-28T13:19:46Z,MEMBER,"sounds good. Minor comment / nit: you don't really need the `astype(np.float)`, the result should already be of dtype `float` since there are missing values after the rolling sum. I don't know about performance but if it does what you asked for then that's good?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-605395619,https://api.github.com/repos/pydata/xarray/issues/3896,605395619,MDEyOklzc3VlQ29tbWVudDYwNTM5NTYxOQ==,9312831,2020-03-28T05:02:59Z,2020-03-28T05:02:59Z,NONE,"Hi @keewis, this is really a smart way, using `rolling` twice. I've refactored the code slightly as: ```python def continuous_meet(cond, count, dim): """""" Continuously meet a given condition along a dimension. """""" _found = cond.rolling(dim={dim:count}, center=True).sum().fillna(0).astype(np.float) detected = ( _found.rolling(dim={dim:count}, center=True) .reduce(lambda a, axis: (a == count).any(axis=axis)) .fillna(False) .astype(bool) ) if count % 2 == 0: return detected.shift({dim:-1}).fillna(False) return detected sst = xr.DataArray( np.array( [0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 0., 0., 1., 0., 0., 1., 1., 1., 1., 1., 1., 0., 0., 0.] ), dims=""time"", coords={""time"": np.arange(24)}, name=""sst"", ) ElNino = continuous_meet(sst > 0.5, count=5, dim='time') sst.plot.step(linewidth=3) sst.where(ElNino).plot.step(linewidth=2) ``` Note that when `count` is a even number, truly centered `rolling` cannot be obtained. So we need to `shift` the result by -1. Is this perfect? I didn't check the performance.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-605084864,https://api.github.com/repos/pydata/xarray/issues/3896,605084864,MDEyOklzc3VlQ29tbWVudDYwNTA4NDg2NA==,14808389,2020-03-27T16:08:22Z,2020-03-27T17:58:15Z,MEMBER,"what about this? ```python In [86]: def detect(arr): ...: thresh = arr > 0.5 ...: n_found = thresh.rolling(dim={""x"": 5}, center=True).sum().fillna(0) ...: detected = ( ...: n_found.rolling(dim={""x"": 5}, center=True) ...: .reduce(lambda a, axis: (a == 5).any(axis=axis)) ...: .fillna(False) ...: .astype(bool) ...: ) ...: return detected ...: ...: arr = xr.DataArray( ...: np.array( ...: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0] ...: ), ...: dims=""x"", ...: coords={""x"": np.arange(24)}, ...: name=""sst"", ...: ) ...: ( ...: arr.to_dataset() ...: .assign(mask=lambda ds: detect(ds.sst)) ...: .assign(selected=lambda ds: ds.sst.where(ds.mask)) ...: ) Out[86]: <xarray.Dataset> Dimensions: (x: 24) Coordinates: * x (x) int64 0 1 2 3 4 5 6 7 8 9 10 ... 14 15 16 17 18 19 20 21 22 23 Data variables: sst (x) int64 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 1 1 0 0 0 mask (x) bool False False False False False ... True False False False selected (x) float64 nan nan nan nan nan 1.0 ... 1.0 1.0 1.0 nan nan nan ```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-604779924,https://api.github.com/repos/pydata/xarray/issues/3896,604779924,MDEyOklzc3VlQ29tbWVudDYwNDc3OTkyNA==,5635139,2020-03-27T02:18:48Z,2020-03-27T02:18:48Z,MEMBER,"OK, that's a bit harder but not impossible. You could take that, run `array.astype(float).where(array).bfill(dim, limit=5)`, or similar? Others will probably have cleaner suggestions...","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-604776072,https://api.github.com/repos/pydata/xarray/issues/3896,604776072,MDEyOklzc3VlQ29tbWVudDYwNDc3NjA3Mg==,9312831,2020-03-27T02:01:54Z,2020-03-27T02:01:54Z,NONE,"Hi @max-sixty, thanks for your kind help. But I found it works not as I expected. If the SST has the values `[..., 0, 0, 1, 1, 1, 1, 1, 0, 0, ...]`, then the method you suggested will give `[..., F, F, F, F, T, F, F, F, F, ...]`. That is only one `True` for a 5 consecutive 1s. But I would expect five `True` like `[..., F, F, T, T, T, T, T, F, F, ...]`. Any suggestion?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763 https://github.com/pydata/xarray/issues/3896#issuecomment-604499916,https://api.github.com/repos/pydata/xarray/issues/3896,604499916,MDEyOklzc3VlQ29tbWVudDYwNDQ5OTkxNg==,5635139,2020-03-26T15:35:19Z,2020-03-26T15:35:19Z,MEMBER,"IIUC, you could have, in order: - rolling 3 month SST - bool on whether that's above 0.5 - rolling 5 month count of that - bool on whether that's equal to 5","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,588126763