Tensorflow: Passing CSV with 3D feature array
<p>My current text file that I intend to use for LSTM training in Tensorflow looks like this:</p>

<pre><code>&gt; 0.2, 4.3, 1.2
&gt; 1.1, 2.2, 3.1
&gt; 3.5, 4.1, 1.1, 4300
&gt; 
&gt; 1.2, 3.3, 1.2
&gt; 1.5, 2.4, 3.1
&gt; 3.5, 2.1, 1.1, 4400
&gt; 
&gt; ...
</code></pre>

<p>There are 3 sequences 3 features vectors with only 1 label for each sample. I formatted this text file so it can be consistent with the LSTM training as the latter requires a time-steps of the sequences or in general, LSTM training requires a 3D tensor (batch, num of time-steps, num of features).</p>

<p>My question: How should I use Numpy or <code>TensorFlow.TextReader</code> in order to reformat the 3x3 sequence vectors and the singleton Labels so it can become compatible with Tensorflow?</p>

<p>Edit: I saw many tutorials on reformatting text or CSV files that has vectors and labels but unfortunately they were for 1 to 1 relationships e.g.</p>

<pre><code>0.2, 4.3, 1.2, Class1
1.1, 2.2, 3.1, Class2
3.5, 4.1, 1.1, Class3
</code></pre>

<p>becomes:</p>

<pre><code>[0.2, 4.3, 1.2, Class1], [1.1, 2.2, 3.1, Class2], [3.5, 4.1, 1.1, Class3]
</code></pre>

<p>which clearly is readable by Numpy and can build vectors easily from it dedicated for simple Feed-Forward NN tasks. But this procedure doesn't actually build an LSTM friendly CSV.</p>

<p>EDIT: The TensorFlow tutorial on CSV formats, covers only 2D arrays as an example. The <code>features = col1, col2, col3</code> doesn't assume that there might be time-steps for each sequence array and hence my question.</p>

<p>I'm a little confused as to whether you are more interested in the <code>numpy</code> array(s) structure, or the csv fomat.</p>

<p>The <code>np.savetxt</code> csv file writer can't readily produce text like:</p>

<pre><code>0.2, 4.3, 1.2
1.1, 2.2, 3.1
3.5, 4.1, 1.1, 4300

1.2, 3.3, 1.2
1.5, 2.4, 3.1
3.5, 2.1, 1.1, 4400
</code></pre>

<p><code>savetxt</code> is not tricky.  It opens a file for writing, and then iterates on the input array, writing it, one row at a time to the file.  Effectively:</p>

<pre><code> for row in arr:
    f.write(fmt % tuple(row))
</code></pre>

<p>where <code>fmt</code> has a <code>%</code> field for each element of the the <code>row</code>.  In the simple case it constructs <code>fmt = delimiter.join(['fmt']*(arr.shape[1]))</code>.  In other words repeating the simgle field <code>fmt</code> for the number of columns.  Or you can give it a multifield <code>fmt</code>.</p>

<p>So you could use normal line/file writing methods to write a custom display.  The simplest is to construct it using the usual <code>print</code> commends, and then redirect those to a file.</p>

<p>But having done that, there's the question of how to read that back into a <code>numpy</code> session.  <code>np.genfromtxt</code> can handle missing data, but you still have to include the delimiters.   It's also trickier to have it read blocks (3 lines separated by a blank line).  It's not impossible, but you have to do some preprocessing.</p>

<p>Of course <code>genfromtxt</code> isn't that tricky either.  It reads the file line by line, converts each line into a list of numbers or strings, and collects those lists in a master list.  Only at the end is that list converted into an array.</p>

<p>I can construct an array like your text with:</p>

<pre><code>In [121]: dt = np.dtype([('lbl',int), ('block', float, (3,3))])
In [122]: A = np.zeros((2,),dtype=dt)
In [123]: A
Out[123]: 
array([(0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]),
       (0, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])], 
      dtype=[('lbl', '&lt;i4'), ('block', '&lt;f8', (3, 3))])
In [124]: A['lbl']=[4300,4400]
In [125]: A[0]['block']=np.array([[.2,4.3,1.2],[1.1,2.2,3.1],[3.5,4.1,1.1]])
In [126]: A
Out[126]: 
array([(4300, [[0.2, 4.3, 1.2], [1.1, 2.2, 3.1], [3.5, 4.1, 1.1]]),
       (4400, [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])], 
      dtype=[('lbl', '&lt;i4'), ('block', '&lt;f8', (3, 3))])
In [127]: A['block']
Out[127]: 
array([[[ 0.2,  4.3,  1.2],
        [ 1.1,  2.2,  3.1],
        [ 3.5,  4.1,  1.1]],

       [[ 0. ,  0. ,  0. ],
        [ 0. ,  0. ,  0. ],
        [ 0. ,  0. ,  0. ]]])
</code></pre>

<p>I can load it from a txt that has all the block values flattened:</p>

<pre><code>In [130]: txt=b"""4300, 0.2, 4.3, 1.2, 1.1, 2.2, 3.1, 3.5, 4.1, 1.1"""
In [131]: txt
Out[131]: b'4300, 0.2, 4.3, 1.2, 1.1, 2.2, 3.1, 3.5, 4.1, 1.1'
</code></pre>

<p><code>genfromtxt</code> can handle a complex dtype, allocating values in order from the flat line list:</p>

<pre><code>In [133]: data=np.genfromtxt([txt],delimiter=',',dtype=dt)
In [134]: data['lbl']
Out[134]: array(4300)
In [135]: data['block']
Out[135]: 
array([[ 0.2,  4.3,  1.2],
       [ 1.1,  2.2,  3.1],
       [ 3.5,  4.1,  1.1]])
</code></pre>

<p>I'm not sure about writing it.  I have have to reshape it into a 10 column  or field array, if I want to use <code>savetxt</code>.</p>

python arrays csv numpy tensorflow