假设我定义了以下类:
class Event(object):
def __init__(self, time):
self.time = time
self.alive = True
def __repr__(self,):
return f"t = {self.time:.2E}"
然后我有一个Event
对象的numpy.ndarray
,按时间排序:
timestamps
>>>> array([t = 5.00E-11, t = 1.51E-08, t = 3.15E-08, t = 4.69E-08], dtype=object)
我想选择例如所有在两个值之间有time
字段的数组元素,并将它们的alive
字段设置为False
。
有办法吗?
我唯一尝试的是使用显式的for循环,但这会变得非常慢:
for i in range(len(timestamps)):
# ...
# element i get selected
for j in range(i, len(timestamps):
if timestamps[i].time < timestamps[j].time < timestamps[i].time + t_dead:
tiemstamps[j].alive = False
而我正在寻找类似
的内容target = timestamps[i].time
timestamps[target < timestamps.time < target + t_dead].alive = False
# I know the syntax is very wrong here
这允许您比较自定义对象。__lt__
和__gt__
实现
编辑:根据OP的评论,我建议使用一些非for循环选项来设置活旗。请注意新的"生活"。事件类的函数。
import numpy as np
class Event(object):
def __init__(self, time):
self.time = time
self.alive = True
def __repr__(self,):
return f"t = {self.time:.2E}"
# this allows you to check equality of two custom objects
def __eq__(self, other):
return self.time == other.time
# this allows you to check "less than" property of two custom objects
def __lt__(self, other):
return self.time < other.time
# this allows you to check "greater than" property of two custom objects
def __gt__(self, other):
return self.time > other.time
def living(self, is_alive: bool):
self.alive = is_alive
timestamps = np.array([Event(1), Event(2), Event(3)])
# filtered timestamps
result = timestamps[(timestamps>Event(1)) & (timestamps<Event(3))]
## here are some alternatives to change the "living" attribute
# use python map function to set the living attribute
list(map(lambda x: x.living(False), result))
# This is a for-loop shorthand
[v.living(False) for v in result]
# apply a vectorized function to all elements of result
np.vectorize(lambda x: x.living(False))(result)
# (also pandas' df.apply())