#python #tensorflow
#python #тензорный поток
Вопрос:
Я хочу выполнить операцию datetime.strptime для тензоров тензорного потока:
def convert_to_date(feat):
return datetime.strptime(feat, DATETIME_DEFAULT_FORMAT).timestamp() if feat else np.nan
DATETIME_FORMAT = '%Y-%m-%d %H:%M'
inputs = tf.constant(['2012-06-19 06:00', '2012-06-19 06:01', '2020-01-02 12:00'])
map_func = lambda feat: tf.py_function(func=convert_date, inp=[feat], Tout=tf.float32)
x = tf.map_fn(fn=map_func, elems=inputs)
Я получил ошибку, потому что аргумент strptime() является тензором, а не строкой:
TypeError: strptime() argument 1 must be str, not tensorflow.python.framework.ops.EagerTensor
Каков обходной путь для этого?
Спасибо!
Ответ №1:
Если возможно быстрое выполнение, вы можете использовать numpy
метод для вычисления тензора, декодирования его в строку и вызова datetime.strptime
его:
def convert_to_date(feat):
return datetime.strptime(feat.numpy().decode("utf-8"), "%Y-%m-%d %H:%M").timestamp() if feat else np.nan
а затем устанавливающая выходную сигнатуру в вызове на map_fn
:
>>> inputs = tf.constant(['2012-06-19 06:00', '2012-06-19 06:01', '2020-01-02 12:00'])
>>> map_func = lambda feat: tf.py_function(func=convert_to_date, inp=[feat], Tout=tf.float32)
>>> tf.map_fn(fn=map_func, elems=inputs, fn_output_signature=tf.float32)
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([1.3400783e 09, 1.3400785e 09, 1.5779628e 09], dtype=float32)>
Если быстрое выполнение не является опцией (т.Е. Вы хотите вызвать эту функцию в tf.data.Dataset
или для использования tf.function
), тогда вам следует рассмотреть функцию numpy и tf.numpy_function
:
def np_convert_to_timestamp(feat):
unix_time = np.datetime64('1970-01-01T00:00:00')
timestamps = (np.array(feat).astype(np.datetime64) - unix_time)/np.timedelta64(1,'s')
return timestamps.astype(np.float32)
И пример вызова функции:
>>> inputs = tf.constant(['2012-06-19 06:00', '2012-06-19 06:01', '2020-01-02 12:00'])
>>> map_func = tf.function(lambda feat: tf.numpy_function(np_convert_to_timestamp, [feat], Tout=tf.float32))
>>> tf.map_fn(fn=map_func, elems=inputs, fn_output_signature=tf.float32)
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([1.3400856e 09, 1.3400856e 09, 1.5779663e 09], dtype=float32)>