【问题标题】:completing a sparse timeline完成一个稀疏的时间线
【发布时间】:2022-01-06 20:52:36
【问题描述】:

随着时间的推移,我对进程状态进行了一些稀疏测量,如下所示:

               tag
2022-01-15  
2022-01-08  #Step3
2022-01-06  #Step2
2021-12-31  
2021-12-28  #Step1

...我想将它们转换成一个完整的系列,我可以用它来绘制时间线,如下所示:

               tag
2021-12-28  #Step1
2021-12-29  #Step1
2021-12-30  #Step1
2021-12-31  #Step1
2022-01-01  #Step1
2022-01-02  #Step1
2022-01-03  #Step1
2022-01-04  #Step1
2022-01-05  #Step1
2022-01-06  #Step2
2022-01-07  #Step2
2022-01-08  #Step3
2022-01-09  #Step3
2022-01-10  #Step3
2022-01-11  #Step3
2022-01-12  #Step3
2022-01-13  #Step3
2022-01-14  #Step3
2022-01-15  #Step3

下面的代码有效,但看起来很丑????我想知道是否有更优雅/更有效的方法来实现这一目标。 另外,我得到了一个SettingWithCopyWarning,我应该能够修复它。

谢谢!!

#! /usr/bin/env python3

import pandas as pd


MY_SAMPLINGS = [
    {'timestamp': '2022-01-15', 'tag': ''}, 
    {'timestamp': '2022-01-08', 'tag': '#Step3'}, 
    {'timestamp': '2022-01-06', 'tag': '#Step2'}, 
    {'timestamp': '2021-12-31', 'tag': ''}, 
    {'timestamp': '2021-12-28', 'tag': '#Step1'}
    ]


myDates = [d['timestamp'] for d in MY_SAMPLINGS]
dates = pd.date_range(myDates[-1],myDates[0])
df = pd.DataFrame(index=dates, columns=['tag'])


for x in range((len(MY_SAMPLINGS)-1),0,-1): 
    startTime = MY_SAMPLINGS[x]['timestamp']
    endTime = MY_SAMPLINGS [x-1]['timestamp']
    if (MY_SAMPLINGS[x]['tag']):
        myTag = MY_SAMPLINGS[x]['tag']
    else:
        myTag = MY_SAMPLINGS[x+1]['tag']
    df.loc[startTime:endTime]['tag'] = myTag

print (df)

【问题讨论】:

    标签: python pandas performance


    【解决方案1】:

    好的,我将分小步分解所有内容,但这只是几行代码,并且比循环更具可扩展性。

    import pandas as pd 
    
    df = pd.DataFrame(MY_SAMPLINGS)
    

    我们首先要将时间戳作为有序时间索引。

    df["timestamp"] = pd.to_datetime(df["timestamp"], format="%Y-%m-%d")
    df = df.set_index("timestamp").sort_index()
    

    这给出了:

                   tag
    timestamp
    2021-12-28  #Step1
    2021-12-31
    2022-01-06  #Step2
    2022-01-08  #Step3
    2022-01-15
    

    然后,每天重新采样并向前填充,这意味着重新采样产生的任何缺失值都将采用之前非缺失值的值。

    df = df.resample("1D").ffill()
    

    这给出了:

                   tag
    timestamp
    2021-12-28  #Step1
    2021-12-29  #Step1
    2021-12-30  #Step1
    2021-12-31
    2022-01-01
    2022-01-02
    2022-01-03
    2022-01-04
    2022-01-05
    2022-01-06  #Step2
    2022-01-07  #Step2
    2022-01-08  #Step3
    2022-01-09  #Step3
    2022-01-10  #Step3
    2022-01-11  #Step3
    2022-01-12  #Step3
    2022-01-13  #Step3
    2022-01-14  #Step3
    2022-01-15
    

    现在,我们仍然有所有这些空字符串,让我们将它们视为空字符串并再次向前填充。

    df = df.replace('', pd.NA).ffill()
    

    现在我们完成了:

                   tag
    timestamp
    2021-12-28  #Step1
    2021-12-29  #Step1
    2021-12-30  #Step1
    2021-12-31  #Step1
    2022-01-01  #Step1
    2022-01-02  #Step1
    2022-01-03  #Step1
    2022-01-04  #Step1
    2022-01-05  #Step1
    2022-01-06  #Step2
    2022-01-07  #Step2
    2022-01-08  #Step3
    2022-01-09  #Step3
    2022-01-10  #Step3
    2022-01-11  #Step3
    2022-01-12  #Step3
    2022-01-13  #Step3
    2022-01-14  #Step3
    2022-01-15  #Step3
    

    【讨论】:

      【解决方案2】:

      您可以尝试在此处使用重采样。请注意,我已经用 Nones 替换了一个空字符串,以便以后可以将 fillna 与 ffill 方法一起使用。

      MY_SAMPLINGS = [
          {'timestamp': '2022-01-15', 'tag': None}, 
          {'timestamp': '2022-01-08', 'tag': '#Step3'}, 
          {'timestamp': '2022-01-06', 'tag': '#Step2'}, 
          {'timestamp': '2021-12-31', 'tag': None}, 
          {'timestamp': '2021-12-28', 'tag': '#Step1'}
          ]
      df = pd.DataFrame(MY_SAMPLINGS).assign(timestamp=lambda x: pd.to_datetime(x["timestamp"])).set_index("timestamp")
      result = df.resample('1D').pad().fillna(method="ffill")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-09
        相关资源
        最近更新 更多