【问题标题】:Find the next non NaN value's timestamp查找下一个非 NaN 值的时间戳
【发布时间】:2021-05-05 16:03:00
【问题描述】:

我有一个如下的数据框:

A    B   datetime
10  NaN  12-03-2020  04:43:11
NaN 20   13-03-2020  04:43:11
NaN NaN  14-03-2020  04:43:11
NaN NaN  15-03-2020  04:43:11
NaN NaN  16-03-2020  04:43:11
NaN 50   17-03-2020  04:43:11
20  NaN  18-03-2020  04:43:11
NaN 30   19-03-2020  04:43:11
NaN NaN  20-03-2020  04:43:11
30  30   21-03-2020  04:43:11
40  NaN  22-03-2020  04:43:11
NaN 10   23-03-2020  04:43:11

这里的逻辑是如果 A 列是 notna() 并且 B 列的下一个最接近的非 NaN 值是 notna() 则返回 B 列的时间戳。

对于这个逻辑,我使用下面的代码:

df['cond1'] = df['A'].notna()

for t in range(1,5): 
    if df['cond1'] == True:
        df['next_ts'] = np.where(df['B'].shift(-t).notna(),df['datetime'].shift(-t),np.datetime64('NaT'))
    else:
        None

对于上面的代码,我收到以下错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

所需的输出如下:

A    B   datetime                next_ts
10  NaN  12-03-2020  04:43:11    NaN 
NaN 20   13-03-2020  04:43:11    NaN 
NaN NaN  14-03-2020  04:43:11    NaN 
NaN NaN  15-03-2020  04:43:11    NaN 
NaN NaN  16-03-2020  04:43:11    NaN 
NaN 50   17-03-2020  04:43:11    NaN 
20  NaN  18-03-2020  04:43:11    19-03-2020  04:43:11
NaN 30   19-03-2020  04:43:11    NaN
NaN NaN  20-03-2020  04:43:11    NaN 
30  30   21-03-2020  04:43:11    22-03-2020  04:43:11
40  NaN  22-03-2020  04:43:11    23-03-2020  04:43:11
NaN 10   23-03-2020  04:43:11    NaN

Someone please help me in achieving my logic. 

【问题讨论】:

  • 是否可以添加预期输出?
  • @jezrael 是更新了所需的输出

标签: python pandas dataframe numpy nan


【解决方案1】:
import datetime

import numpy as np
import pandas as pd


df = pd.DataFrame({
    "A": [10, None, None, None, None, None, 20, None, None, 30, 40, None],
    "B": [None, 20, None, None, None, 50, None, 30, None, 30, None, 10],
    "datetime": [datetime.datetime(2020, 3, 12, 4, 43, 11) + datetime.timedelta(days=i) for i in range(12)]
}).astype({"A": "Int64", "B": "Int64"})

df["next_ts"] = np.where(df.B.notnull(), df.datetime, None).astype("datetime64[ns]")  # puts the timestamp where B is set
df["next_ts"] = df.next_ts.fillna(method="bfill")  # propagates the values of next_ts backward where they are null
df["next_ts"] = np.where(df.A.notnull(), df.next_ts, None).astype("datetime64[ns]")  # eliminates the values of next_ts where A is null

print(df)



       A     B            datetime             next_ts
0     10  <NA> 2020-03-12 04:43:11 2020-03-13 04:43:11
1   <NA>    20 2020-03-13 04:43:11                 NaT
2   <NA>  <NA> 2020-03-14 04:43:11                 NaT
3   <NA>  <NA> 2020-03-15 04:43:11                 NaT
4   <NA>  <NA> 2020-03-16 04:43:11                 NaT
5   <NA>    50 2020-03-17 04:43:11                 NaT
6     20  <NA> 2020-03-18 04:43:11 2020-03-19 04:43:11
7   <NA>    30 2020-03-19 04:43:11                 NaT
8   <NA>  <NA> 2020-03-20 04:43:11                 NaT
9     30    30 2020-03-21 04:43:11 2020-03-21 04:43:11
10    40  <NA> 2020-03-22 04:43:11 2020-03-23 04:43:11
11  <NA>    10 2020-03-23 04:43:11                 NaT

【讨论】:

  • 实际上,我已经更新了所需的输出。你能帮我在不放弃 NaN 的情况下做到这一点吗?
  • 进行了编辑。请检查第一行的预期数据,这似乎有点不一致。
猜你喜欢
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多