下面的代码是一个执行基于列的过滤的函数示例:
def filter_cols(x, DateTime):
from datetime import datetime
# dt1, dt2 are tuples of the form (int, <datetime.datetime object>)
# checks if the difference, in days,
# between two datetime objects is at least equal to 'days'
cond = lambda dt1, dt2, days=150: abs((dt1[1] - dt2[1]).days) >= days
def filt(it, li=[]):
try:
if not li:
li.append(next((xi, di) for xi, di in it if xi >= 25))
li.append(next(df for df in it if cond(li[-1], df) and df[0] >= 25))
filt(it, li)
except StopIteration:
pass
finally:
return li
# preprocessing step
# parse DateTime elements into datetime objects
dt = list(map(lambda s: datetime.strptime(s, '%Y-%m-%d'), DateTime))
# main step
# call filtering function
li_tup = filt(zip(x, dt))
# if li_tup is empty return two empty lists
if not li_tup:
return [], []
# postprocessing step
# split the list of tuples into two tuples
x_filt, dt_filt = zip(*li_tup)
# format dates back to their string representation
dt_filt = list(map(lambda dt: dt.strftime('%Y-%m-%d'), dt_filt))
return list(x_filt), dt_filt
请记住,函数可以写得更密集,但为了清楚起见,步骤被分解了。
虽然没有明确说明,但我假设您的 DateTime 列表
是按时间升序排列的。
做了这个假设,上面例子背后的主要思想
是首先将DateTime 列表解析为一个对象
可以操作日期数据并提供天差功能。
这是通过使用内置的datetime 模块实现的,但您可以使用最适合您的任何方式。 map() 函数将datetime 类的strptime() 类方法应用于DateTime,以便将字符串元素解析为上述日期时间对象,并返回一个转换为列表的迭代器。
filt(it, li: list=[]) 函数接受一个迭代器和一个默认为空列表但可以初始化的参数,应该是必需的。该列表包含有效的 x 和 DateTime 元素对的元组,例如[(29, datetime.datetime(2005, 10, 3, 0, 0)), (25, datetime.datetime(2006, 11, 4, 0, 0))]
当li 为空列表时,filt() 内的以下块附加第一个x,
Datetime 到列表的元组,这样x 至少等于25:
if not li:
li.append(next((xi, di) for xi, di in it if xi >= 25))
为了过滤DateTime 列,迭代将继续,直到找到满足问题陈述中设置的条件的 x 对元组为止。如果 li 的最后一个元组中的 datatime 对象与迭代器产生的当前元组中的 datetime 对象之间的差异至少有 150 天,则实用函数 cond(li[-1], df) 返回 True。另一个条件是 x(df[0],当前元组的第一个元素)必须至少再次等于 25。这是我的假设,因为问题陈述中没有明确说明如果其对应的x 小于25,则是否允许满足日期差异条件的一对。如果是这种情况,请随意省略第二个条件df[0] >= 25。
next(df for df in it if cond(li[-1], df) and df[0] >= 25)
和
cond = lambda dt1, dt2, days=150: abs((dt1[1] - dt2[1]).days) >= days
两个对象之间的天数差异存储在日期时间的days 属性中。
然后函数在next 有效元组附加到li 后递归调用自身。
当it 迭代器被消耗时递归结束,引发StopIteration 异常。
后处理步骤,通过解开filt() 的输出然后调用zip(),将元组列表转换为两个元组。
x_filt, dt_filt = zip(*li_tup)
另外一步,将过滤后的datetime 对象列表格式化回字符串。
filter_cols() 函数返回两个过滤列。
示例运行:
>>> filter_cols(x, DateTime)
([29, 25, 28], ['2005-10-03', '2006-11-04', '2010-01-21'])