#python #pandas #numpy #tensorflow
Вопрос:
Мне нужно загрузить из текстовых файлов строки, содержащие строковые представления 2D-массивов, для последующего использования при обучении Tensorflow CNN, но я не могу преобразовать строки в формат, который нравится Tensorflow. Я пробовал всевозможные комбинации apply/map/различных функций, но всегда получал какую-то загадочную ошибку. Ниже приведен пример кода игрушки, который близок к работе, но все равно выдает ошибку:
ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray)
import tensorflow as tf
import numpy as np
import pandas as pd
from ast import literal_eval
def df_to_dataset(dataframe):
Y = tf.convert_to_tensor( dataframe['Y'].values )
X = tf.convert_to_tensor( dataframe['X'].apply(literal_eval).apply(np.array).values )
return tf.data.Dataset.from_tensor_slices( ( X , Y ) )
data = [[ 1, "[[0,1],[0,1]]" ] , [ 0 , "[[1,0],[1,0]]" ]]
df = pd.DataFrame(data, columns=['Y','X'])
dataset = df_to_dataset(df)
for feature in dataset.take(1):
print( feature )
Комментарии:
1. Как вы ожидаете, что конечный кадр данных будет выглядеть в вашем примере? Для меня это не очевидно.
Ответ №1:
Таким образом, ваш фрейм данных отображается как:
In [161]: df
Out[161]:
Y X
0 1 [[0,1],[0,1]]
1 0 [[1,0],[1,0]]
хотя это не показывает строковые кавычки.
In [162]: df['Y'].values
Out[162]: array([1, 0])
X
Столбец представляет собой 1d массив строк, тип объекта dtype:
In [163]: df['X'].values
Out[163]: array(['[[0,1],[0,1]]', '[[1,0],[1,0]]'], dtype=object)
С помощью eval values
теперь представляет собой массив списков:
In [164]: from ast import literal_eval
In [165]: df['X'].apply(literal_eval)
Out[165]:
0 [[0, 1], [0, 1]]
1 [[1, 0], [1, 0]]
Name: X, dtype: object
In [166]: df['X'].apply(literal_eval).values
Out[166]: array([list([[0, 1], [0, 1]]), list([[1, 0], [1, 0]])], dtype=object)
Но если вместо этого мы извлекем его в виде списка:
In [168]: df['X'].apply(literal_eval).to_list()
Out[168]: [[[0, 1], [0, 1]], [[1, 0], [1, 0]]]
Мы можем легко превратить это в массив:
In [169]: np.array(_)
Out[169]:
array([[[0, 1],
[0, 1]],
[[1, 0],
[1, 0]]])
Возвращаясь к форме массива, мы можем «уменьшить» это, используя stack
In [170]: np.stack(df['X'].apply(literal_eval).values)
Out[170]:
array([[[0, 1],
[0, 1]],
[[1, 0],
[1, 0]]])
stack
похоже concatenate
или vstack
за исключением того, что это добавляет измерение, действуя более похоже np.array
.
Теперь преобразование тензорного потока должно работать.
Ваш второй apply
, только изменяет массив списков в массив массивов.
In [174]: df['X'].apply(literal_eval).apply(np.array).values
Out[174]:
array([array([[0, 1],
[0, 1]]), array([[1, 0],
[1, 0]])], dtype=object)
np.stack
работает и над этим тоже.