Tensorflow:使用3D要素数组传递CSV

时间:2016-09-18 19:41:35

标签: python arrays csv numpy tensorflow

我打算在Tensorflow中用于LSTM培训的当前文本文件如下所示:

> 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
> 
> ...

有3个序列3个特征向量,每个样本只有1个标签。我格式化了这个文本文件,因此它可以与LSTM训练保持一致,因为后者需要序列的时间步长,或者通常,LSTM训练需要3D张量(批量,时间步数,特征数量)。 / p>

我的问题:我应该如何使用Numpy或TensorFlow.TextReader重新格式化3x3序列向量和单例标签,以便它可以与Tensorflow兼容?

编辑:我看过许多关于重新格式化文本或CSV文件的教程,这些教程有矢量和标签,但不幸的是它们是1对1的关系,例如。

0.2, 4.3, 1.2, Class1
1.1, 2.2, 3.1, Class2
3.5, 4.1, 1.1, Class3

变为:

[0.2, 4.3, 1.2, Class1], [1.1, 2.2, 3.1, Class2], [3.5, 4.1, 1.1, Class3]

显然可以被Numpy读取,并且可以轻松地构建向量,专用于简单的前馈NN任务。但是这个程序实际上并不构建LSTM友好的CSV。

编辑:关于CSV格式的TensorFlow教程,仅以2D阵列为例。 features = col1, col2, col3并不假设每个序列数组都有时间步长,因而我的问题就是。

2 个答案:

答案 0 :(得分:1)

更新:除了普遍的答案:

df.stack().to_csv('d:/temp/1D.csv', index=False)

1D.csv:

0.2
4.3
1.2
4300.0
1.1
2.2
3.1
4300.0
3.5
4.1
1.1
4300.0
1.2
3.3
1.2
4400.0
1.5
2.4
3.1
4400.0
3.5
2.1
1.1
4400.0

OLD回答:

这是一个熊猫解决方案。

假设我们有以下文本文件:

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

代码:

import pandas as pd

In [95]: fn = r'D:\temp\.data\data.txt'

In [96]: df = pd.read_csv(fn, sep=',', skipinitialspace=True, header=None, names=list('abcd'))

In [97]: df
Out[97]:
     a    b    c       d
0  0.2  4.3  1.2     NaN
1  1.1  2.2  3.1     NaN
2  3.5  4.1  1.1  4300.0
3  1.2  3.3  1.2     NaN
4  1.5  2.4  3.1     NaN
5  3.5  2.1  1.1  4400.0

In [98]: df.d = df.d.bfill()

In [99]: df
Out[99]:
     a    b    c       d
0  0.2  4.3  1.2  4300.0
1  1.1  2.2  3.1  4300.0
2  3.5  4.1  1.1  4300.0
3  1.2  3.3  1.2  4400.0
4  1.5  2.4  3.1  4400.0
5  3.5  2.1  1.1  4400.0

现在您可以将其保存回CSV:

df.to_csv('d:/temp/out.csv', index=False, header=None)

d:/temp/out.csv:

0.2,4.3,1.2,4300.0
1.1,2.2,3.1,4300.0
3.5,4.1,1.1,4300.0
1.2,3.3,1.2,4400.0
1.5,2.4,3.1,4400.0
3.5,2.1,1.1,4400.0

答案 1 :(得分:1)

我对你是否对numpy数组结构或csv fomat更感兴趣感到有点困惑。

np.savetxt csv文件编写者不能轻易生成如下文字:

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

savetxt并不棘手。它打开一个文件进行写入,然后在输入数组上进行迭代,一次一行地写入文件。有效:

 for row in arr:
    f.write(fmt % tuple(row))

其中fmt%的每个元素都有一个row字段。在简单的情况下,它构造fmt = delimiter.join(['fmt']*(arr.shape[1]))。换句话说,为列数重复simgle字段fmt。或者你可以给它一个多字段fmt

因此,您可以使用普通的行/文件写入方法来编写自定义显示。最简单的方法是使用通常的print表彰来构建它,然后将它们重定向到文件。

但是这样做了,那就是如何将其读回numpy会话的问题。 np.genfromtxt可以处理丢失的数据,但您仍然必须包含分隔符。让它读取块(3行用空行分隔)也比较棘手。这不是不可能的,但你必须做一些预处理。

当然genfromtxt也不是那么棘手。它逐行读取文件,将每行转换为数字或字符串列表,并在主列表中收集这些列表。只有在最后才将该列表转换为数组。

我可以使用以下内容构建一个类似文本的数组:

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', '<i4'), ('block', '<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', '<i4'), ('block', '<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. ]]])

我可以从包含所有块值展平的txt加载它:

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'

genfromtxt可以处理复杂的dtype,从平面列表中按顺序分配值:

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

我不确定要写它。如果我想使用savetxt,我必须将其重塑为10列或字段数组。