【问题标题】:Add data for the missing dates based on previous hour data in pandas根据 pandas 中前一小时的数据添加缺失日期的数据
【发布时间】:2021-05-06 07:48:12
【问题描述】:

我有一个如下的数据框:-

id creTimestamp CPULoad instnceId
0 2021-01-22 18:00:00 22.0 instanceA
1 2021-01-22 19:00:00 22.5 instanceA
2 2021-01-22 20:00:00 23.5 instanceA
3 2021-01-22 18:00:00 24.0 instanceB
4 2021-01-22 19:00:00 24.5 instanceB
5 2021-01-22 20:00:00 22.5 instanceB
6 2021-01-24 18:00:00 23.0 instanceA
7 2021-01-24 19:00:00 23.5 instanceA
8 2021-01-24 20:00:00 24.0 instanceA
9 2021-01-24 18:00:00 25.5 instanceB
10 2021-01-24 19:00:00 28.5 instanceB
11 2021-01-24 20:00:00 23.5 instanceB

缺课日期如下:

2021-01-23 2021-01-25

我还想用之前的日期填充 2021-01-23 和 2021-01-25 的行。例如,应考虑 22 日期 HR 数据。 我有一个巨大的数据集,其中日期的整个数据可能会丢失 2 小时。 日期也可以从未来的日期范围生成。 2021-02-01 18:00:00 到 2021-02-02 18:00:00 的示例

更新的数据框应该如下:-

id creTimestamp CPULoad instnceId
0 2021-01-22 18:00:00 22.0 instanceA
1 2021-01-22 19:00:00 22.5 instanceA
2 2021-01-22 20:00:00 23.5 instanceA
3 2021-01-22 18:00:00 24.0 instanceB
4 2021-01-22 19:00:00 24.5 instanceB
5 2021-01-22 20:00:00 22.5 instanceB
6 2021-01-23 18:00:00 22.0 instanceA
7 2021-01-23 19:00:00 22.5 instanceA
8 2021-01-23 20:00:00 23.5 instanceA
9 2021-01-23 18:00:00 24.0 instanceB
10 2021-01-23 19:00:00 24.5 instanceB
11 2021-01-23 20:00:00 22.5 instanceB
12 2021-01-24 18:00:00 23.0 instanceA
13 2021-01-24 19:00:00 23.5 instanceA
14 2021-01-24 20:00:00 24.0 instanceA
15 2021-01-24 18:00:00 25.5 instanceB
16 2021-01-24 19:00:00 28.5 instanceB
17 2021-01-24 20:00:00 23.5 instanceB
18 2021-01-25 18:00:00 23.0 instanceA
19 2021-01-25 19:00:00 23.5 instanceA
20 2021-01-25 20:00:00 24.0 instanceA
21 2021-01-25 18:00:00 25.5 instanceB
22 2021-01-25 19:00:00 28.5 instanceB
23 2021-01-25 20:00:00 23.5 instanceB

日期范围可以是过去 7 天。

请帮我解决这个要求。

谢谢

【问题讨论】:

  • 对于缺失的行,您要在 CPULoad 和 InstanceID 列中填写什么?
  • 上一个日期和同一小时的数据。如果你看到更新的数据框,CPUload 有 2021-01-22 19:00:00 的数据,即 22。实例也应该相同。就像我的例子中的实例 A

标签: python pandas dataframe datetime time


【解决方案1】:

这是fill values的延续

  • 生成一个结合了采样小时数和实例的 DF (df2)
  • 这会生成 15 行,因为 instanceA 有 3 次,instanceB 有 2 次,跨越 3 个日期 (2+3)*3
  • 然后使用相同的技术来填充 CPULoad 和合成的 memload
  • 针对 pandas 1.0.1 和 1.2.0 进行了测试
import pandas as pd
import io
import datetime as dt
import numpy as np
df = pd.read_csv(io.StringIO("""id  creTimestamp    CPULoad instnceId
0   2021-01-22 18:00:00 22.0    instanceA
1   2021-01-22 19:00:00 22.0    instanceA
2   2021-01-22 20:00:00 23.0    instanceB
3   2021-01-23 18:00:00 24.0    instanceA
4   2021-01-23 20:00:00 22.0    instanceA
5   2021-01-24 18:00:00 23.0    instanceB
6   2021-01-24 20:00:00 23.5    instanceA
"""), sep="\t", index_col=0)

df.creTimestamp = pd.to_datetime(df.creTimestamp)
df["memload"] = np.random.random(len(df))

# generate a DF for each time in instance in each date
df2 = (pd.merge(
    # for each time in instance
    df.assign(timestamp=df.creTimestamp.dt.time)
        .loc[:,["instnceId","timestamp"]]
        .drop_duplicates()
        .assign(foo=1),
    # for each date
    df.creTimestamp.dt.date.drop_duplicates().to_frame().assign(foo=1),
    on="foo"
).assign(creTimestamp=lambda dfa: dfa.apply(lambda r: dt.datetime.combine(r["creTimestamp"], r["timestamp"]), axis=1))
 .drop(columns="foo")
       # merge values back..
 .merge(df, on=["creTimestamp", "instnceId"], how="left")
)

# now get values to fill NaN
df2 = (df2.merge(df2.dropna().drop_duplicates(subset=["instnceId","timestamp"], keep="last"),
         on=["timestamp","instnceId"], suffixes=("","_pre"))
 .assign(CPULoad=lambda dfa: dfa.CPULoad.fillna(dfa.CPULoad_pre))
 .assign(memload=lambda dfa: dfa.memload.fillna(dfa.memload_pre))

)

输出

    instnceId timestamp        creTimestamp  CPULoad    creTimestamp_pre  CPULoad_pre
0   instanceA  18:00:00 2021-01-22 18:00:00     22.0 2021-01-23 18:00:00         24.0
1   instanceA  18:00:00 2021-01-23 18:00:00     24.0 2021-01-23 18:00:00         24.0
2   instanceA  18:00:00 2021-01-24 18:00:00     24.0 2021-01-23 18:00:00         24.0
3   instanceA  19:00:00 2021-01-22 19:00:00     22.0 2021-01-22 19:00:00         22.0
4   instanceA  19:00:00 2021-01-23 19:00:00     22.0 2021-01-22 19:00:00         22.0
5   instanceA  19:00:00 2021-01-24 19:00:00     22.0 2021-01-22 19:00:00         22.0
6   instanceB  20:00:00 2021-01-22 20:00:00     23.0 2021-01-22 20:00:00         23.0
7   instanceB  20:00:00 2021-01-23 20:00:00     23.0 2021-01-22 20:00:00         23.0
8   instanceB  20:00:00 2021-01-24 20:00:00     23.0 2021-01-22 20:00:00         23.0
9   instanceA  20:00:00 2021-01-22 20:00:00     23.5 2021-01-24 20:00:00         23.5
10  instanceA  20:00:00 2021-01-23 20:00:00     22.0 2021-01-24 20:00:00         23.5
11  instanceA  20:00:00 2021-01-24 20:00:00     23.5 2021-01-24 20:00:00         23.5
12  instanceB  18:00:00 2021-01-22 18:00:00     23.0 2021-01-24 18:00:00         23.0
13  instanceB  18:00:00 2021-01-23 18:00:00     23.0 2021-01-24 18:00:00         23.0
14  instanceB  18:00:00 2021-01-24 18:00:00     23.0 2021-01-24 18:00:00         23.0

【讨论】:

  • 我收到错误,不再支持将列表喜欢传递给 .loc 或 [] 并带有任何缺失的标签,请参阅 pandas.pydata.org/pandas-docs/stable/user_guide/…'。熊猫版本是 1.0.5。其次,我想要不在此范围内的日期。例如 2021-02-01 18:00:00 到 2021-02-02 18:00:00。因此,与原始 DF 合并就是给出 NaN。知道我们如何转发不在数据集时间范围内的时间的填充值。
  • 熊猫版? pd.__version__我用的是1.2.0
  • 熊猫版本是 1.0.5。关于合并数据集 min() 和 max() 之外的日期范围的任何线索?
  • 您对所需行的逻辑很奇怪...... instanceA 有 3 次(18:00、19:00、20:00),instanceB 有 2 次(18:00、20:00)和3 个日期,因此预期的行数应为 (3+2)*5 = 15
  • 基本逻辑是每个时间戳,每个实例应该有 2 个条目。一个实例A,实例B。但这不是我担心的。我可以基于每个实例创建 2 个 diff DF 并将它们合并,但挑战是填充未来日期的值。
猜你喜欢
  • 2013-10-19
  • 2021-06-28
  • 2020-03-10
  • 1970-01-01
  • 2021-04-06
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
相关资源
最近更新 更多