операция datetime.strptime(), получающая тензоры тензорного потока вместо строки

#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)>