如何在Numpy.Where()函数中快速将字符串格式的Numpy数组日期时间与日期时间变量进行比较

0 投票
2 回答
48 浏览
提问于 2025-04-14 16:07

大家好,
我有一个程序需要对一大堆数据进行排序。
这份数据包含以下几列信息:

序列号 信息日期 登录日期
SNXXXXXX 2023年10月12日 12:50 2023年12月14日 14:30
SNXXXXX1 2024年2月29日 13:40 2024年2月10日 10:00
SNXXXXX4 无效日期

我需要做的是检查信息日期登录日期是否包含字符串'无效日期',或者检查信息日期是否超过三个月,或者登录日期是否超过三十天。
在第一种情况下,我使用了numpy.where(),没有遇到问题,因为数据已经是字符串格式。但在其他情况下,我遇到了大麻烦,因为每个NumpyArray的元素都是字符串,无法与numpy.where()中的日期时间值进行比较。
这是我在第一种情况中使用的代码:

import pandas as pd
from datetime import datetime, timedelta
import time
import numpy as np
source_data = pd.read_excel("./documents/data.xlsx")


three_months_ago = datetime.now() - timedelta(days=90)
thirty_days_ago = datetime.now() - timedelta(days=30)



#Get the values that are "Invalid date"
print(source_data.iloc[
    np.where(source_data["Login_Date"].values == "Invalid date")])

我尝试使用strptime()函数将数据转换为datetime格式,像这样:

format = str("%d/%m/%Y %H:%M")
print(np.where(datetime.strptime(source_data["Login_Date"], format) < thirty_days_ago))

预期的输出应该是:

序列号 信息日期 登录日期
SNXXXXX1 2024年2月29日 13:40 2024年2月10日 10:00

2 个回答

0

这段代码的意思是……

首先,它会执行一些操作,然后根据条件判断来决定接下来要做什么。这里面可能会有循环,也可能会有判断语句,具体要看代码的内容。

总之,这段代码的目的是为了实现某个功能,可能是处理数据、显示信息或者与用户互动等。

如果你对某些部分不太明白,可以逐行分析,看看每一行代码在做什么,慢慢就能理解了。

记得多动手实践,写写代码,才能更快上手哦!

    import pandas as pd
    import numpy as np
    from datetime import timedelta, date
    from dateutil.relativedelta import relativedelta
    
    # Creating sample data
    data = {
        "Serials": ["SNXXXXXX", "SNXXXXX1", "SNXXXXX4"],
        "Info_Date": ['10/12/2023 12:50', '29/02/2024 13:40',np.nan],
        "Login_Date": ["14/12/2023 14:30", "10/02/2024 10:00", "Invalid date"]
    }
    
    df = pd.DataFrame(data)
    
    # create a copy of two columns
    df['Info_Date_test'] = pd.to_datetime(df['Info_Date'], format='%d/%m/%Y %H:%M').dt.strftime('%Y-%m-%d')
    df['Login_Date_test'] = pd.to_datetime(df['Login_Date'], format='%d/%m/%Y %H:%M', errors='coerce').dt.strftime('%Y-%m-%d')
    
    # if either an Info_Date or Login_date contains the string 'Invalid date'

   df.iloc[np.where((df['Login_Date'] == "Invalid date") | (df['Info_Date'] == "Invalid date"))[0]]
    
    # if the Info_Date is older than three months
    three_months_date = date.today() + relativedelta(months=-3)
    filtered_df = df.iloc[np.where(pd.to_datetime(df['Info_Date_test'])  < pd.to_datetime(three_months_date))[0]]

    # if the Login_Date is older than thirty days.
    thirty_days_date = date.today() + relativedelta(days=-30)
    filtered_df_1 = df.iloc[np.where(pd.to_datetime(df['Login_Date_test'])  < pd.to_datetime(thirty_days_date))[0]]
0

把你原来的日期保持为字符串格式,然后再复制一份变成日期时间格式:

# create a copy of the date columns as datetime
tmp = df[['Info_Date', 'Login_Date']].apply(pd.to_datetime,
                                            dayfirst=True, errors='coerce')

today = pd.Timestamp('today')
# Timestamp('2024-03-14 01:23:45.678900')

# is either date invalid?
m1 = df[['Info_Date', 'Login_Date']].eq('Invalid date').any(axis=1)
# is Info_Date older than 3 months?
m2 = tmp['Info_Date'].lt(today-pd.DateOffset(months=3))
# is Login_Date older than 30 days?
m3 = tmp['Login_Date'].rsub(today).gt('30D')

df[['m1', 'm2', 'm3']] = m1, m2, m3

输出结果:

    Serials         Info_Date        Login_Date     m1     m2     m3
0  SNXXXXXX  10/12/2023 12:50  14/12/2023 14:30  False  False   True
1  SNXXXXX1  29/02/2024 13:40  10/02/2024 10:00   True  False  False
2  SNXXXXX4               NaN      Invalid date   True   True  False

撰写回答