首页 > 解决方案 > 将数据框列中的时间戳与熊猫进行比较

问题描述

假设我有一个这样的数据框

df1:

         datetime1                datetime2             
0   2021-05-09 19:52:14      2021-05-09 20:52:14  
1   2021-05-09 19:52:14      2021-05-09 21:52:14 
2           NaN                      NaN
3  2021-05-09 16:30:14               NaN
4           NaN                      NaN
5  2021-05-09 12:30:14        2021-05-09 14:30:14

我想比较 datetime1 和 datetime2 中的时间戳,并用它们之间的差异创建一个新列。

在某些情况下,我在 datetime1 和 datetime2 中没有值,或者在 datatime1 中有值但在 datatime2 中没有值,因此是否有可能的方法在“差异”列中获取 NaN(如果有)在 datetime1 和 2 中没有时间戳,如果仅在 datetime1 中有时间戳,则获取与 datetime.now() 相比的差异并将其放在另一列中。

理想的df输出:

         datetime1             datetime2          Difference in H:m:s    Compared with datetime.now()
0   2021-05-09 19:52:14     2021-05-09 20:52:14       01:00:00                 NaN
1   2021-05-09 19:52:14     2021-05-09 21:52:14       02:00:00                 NaN
2           NaN                    NaN                  NaN                    NaN
3   2021-05-09 16:30:14            NaN                  NaN                e.g(04:00:00)
4           NaN                    NaN                  NaN                    NaN
5  2021-05-09 12:30:14    2021-05-09 14:30:14         02:00:00                 NaN

我尝试了@AndrejKesely 的解决方案,但如果 datetime1 和 datetime2 中没有时间戳,它会失败:

def strfdelta(tdelta, fmt):
    d = {"days": tdelta.days}
    d["hours"], rem = divmod(tdelta.seconds, 3600)
    d["minutes"], d["seconds"] = divmod(rem, 60)
    return fmt.format(**d)


# if datetime1/datetime2 aren't already datetime, apply `.to_datetime()`:
df["datetime1"] = pd.to_datetime(df["datetime1"])
df["datetime2"] = pd.to_datetime(df["datetime2"])

df["Difference in H:m:s"] = df.apply(
    lambda x: strfdelta(
        x["datetime2"] - x["datetime1"],
        "{hours:02d}:{minutes:02d}:{seconds:02d}",
    ),
    axis=1,
)
print(df)

标签: pythonpython-3.xpandasdataframecompare

解决方案


您可以先用值替换NaN列中的datetime2所有datetime.now值。因此,如果isdatetime1与现在进行比较会更容易。datetime1NaN

你可以这样做:

df["datetime2"] = df["datetime2"].fillna(value=pandas.to_datetime('today').normalize(),axis=1)

然后你只剩下两个条件:

  • 如果datetime1column 为空,则结果为NaN
  • datetime1否则,结果是和列之间的差异datetime2(因为列中没有NaN剩余datetime2)。

您可以使用以下方法执行此操作:

import numpy as np

df["Difference in H:m:s"] = np.where(
    df["datetime1"].isnull(),
    pd.NA,
    df["datetime2"] - df["datetime1"]
)

您最终可以Difference in H:m:s使用您提供的功能将您的格式设置为所需的格式:

def strfdelta(tdelta, fmt):
    d = {"days": tdelta.days}
    d["hours"], rem = divmod(tdelta.seconds, 3600)
    d["minutes"], d["seconds"] = divmod(rem, 60)
    return fmt.format(**d)


df["Difference in H:m:s"] = df.apply(
    lambda x: strfdelta(
        x["Difference in H:m:s"],
        "{hours:02d}:{minutes:02d}:{seconds:02d}",
    ),
    axis=1,
)

完整的代码是:

import numpy as np

# if datetime1/datetime2 aren't already datetime, apply `.to_datetime()`:
df["datetime1"] = pd.to_datetime(df["datetime1"])
df["datetime2"] = pd.to_datetime(df["datetime2"])

df["datetime2"] = df["datetime2"].fillna(value=pandas.to_datetime('today').normalize(),axis=1)

df["Difference in H:m:s"] = np.where(
    df["datetime1"].isnull(),
    pd.NA,
    df["datetime2"] - df["datetime1"]
)

def strfdelta(tdelta, fmt):
    d = {"days": tdelta.days}
    d["hours"], rem = divmod(tdelta.seconds, 3600)
    d["minutes"], d["seconds"] = divmod(rem, 60)
    return fmt.format(**d)


df["Difference in H:m:s"] = df.apply(
    lambda x: strfdelta(
        x["Difference in H:m:s"],
        "{hours:02d}:{minutes:02d}:{seconds:02d}",
    ),
    axis=1,
)

推荐阅读