如何在Numpy.Where()函数中快速将字符串格式的Numpy数组日期时间与日期时间变量进行比较
大家好,
我有一个程序需要对一大堆数据进行排序。
这份数据包含以下几列信息:
序列号 | 信息日期 | 登录日期 |
---|---|---|
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