【问题标题】:Numpy savetxt heterogenous dataNumpy savetxt 异构数据
【发布时间】:2014-02-07 20:18:54
【问题描述】:

我有两个数组 A 和 B,这样:

A.shape 是 (N, 1) 并且 dtype 是 int。 B.shape 是 (N, M),dtype 是 float。

数组 A 包含 ids/序列号。信息。我想在single file with their dtypes preserved 中写 A 和 B,这样每一行都包含 A[i] 和 B[i, :] 即

A[0], B[0, 0], B[0, 1], ..... , B[0, M-1]
A[1], B[1, 0], B[1, 1], ..... , B[1, M-1]
.
.
.
and so on.

我该怎么做?

【问题讨论】:

  • @wwii 我尝试将 A 和 B 连接成一个,这样 A 成为新矩阵的第一列,但 int dtype 被转换为 float。
  • 糟糕...重读问题后,我看到A 是int,所以请参阅@HYRY 的答案。我写了我的答案,认为A 可能包含字符串。我的答案仍然有效,但 HYRY 的要简单得多。

标签: python numpy scipy scikit-learn


【解决方案1】:

使用fmt="%g"调用savetxt()

import numpy as np
a = np.random.randint(0, 100, 10)
b = np.random.rand(10, 3)

v = np.hstack((a[:,None],b))

import io

t = io.BytesIO()

np.savetxt(t, v, fmt="%g", delimiter=",")
print t.getvalue()

这是输出:

58,0.565189,0.865103,0.508969
23,0.916723,0.921158,0.0831125
59,0.277719,0.0093567,0.842342
2,0.647174,0.841386,0.26473
98,0.397821,0.552821,0.16494
62,0.369808,0.146442,0.569618
35,0.703737,0.288476,0.433288
94,0.756107,0.396098,0.896038
67,0.638921,0.891554,0.680056
82,0.449198,0.978571,0.116202

【讨论】:

  • 你可以解释一下变量t是什么吗? span>
  • 您可以将t作为内存中的文件。 span>
【解决方案2】:

(我读的太快了,错过了 A 一个整数数组。下面可能有点过头了,但我会留在这里,以防有人需要混合字符串和浮点数。)

如果数组是相同的数据类型,您可以将它们连接起来,savetxt 就可以正常工作。如果A 是一个字符串数组,那将不起作用。要让savetxt 将此异构数据打印到文件中,您需要使用structured array。这是一种方法。

这个想法是创建一个结构化数组,其第一个字段是一个字符串 (保存ID),其剩余的M个字段是浮点数。 为了方便用给定的数组填充这个数组,我们将这样做 分两步。

首先,我们将创建一个结构化数组,其第一个字段是字符串 并且其第二个字段本身就是一个 M 个浮点值的数组。 这个数据类型在脚本中是dt2,对应的数组是 data2。这允许我们使用 ab 填充数组 简单的赋值 data2['a'] = adata2['b'] = b

接下来我们为这个数组创建一个视图,在脚本中称为data, 使用数据类型 dtallM+1 字段。第一个字段是 字符串,其余为浮点数。

现在我们可以使用savetxtdata 写入文件。提供格式 对于与其他字段不同的第一个字段,我们将构建一个 整行的完整格式字符串,并将其作为fmt savetxt的参数。

import numpy as np

# Example data.
a = np.array(['A001', 'A019', 'A344', 'A742'])
b = np.linspace(0, 1, 16, endpoint=False).reshape(4,4)

# Create a data dtype with two fields.  The first field has the same
# data type as `a`.  The second has the same fundamental data type as `b`,
# repeated N times.  If you print dt2 using the above data, you'll see
#  [('a', 'S4'), ('b', '<f8', (4,))]
dt2 = np.dtype([('a', a.dtype.str)] +
               [('b', b.dtype.str, b.shape[1])])

# Create an empty array using `dt2`, and fill it with `a` and `b`.
data2 = np.empty(len(a), dtype=dt2)
data2['a'] = a
data2['b'] = b

# Create a data type with N+1 fields.  If you print `dtall`, you'll see
#  [('a', 'S4'), ('f1', '<f8'), ('f2', '<f8'), ('f3', '<f8'), ('f4', '<f8')]
dtall = np.dtype([('a', a.dtype.str)] + b.dtype.descr*b.shape[1])

# Create a view of the same data, but with data type `dtall`.
data = data2.view(dtall)

# Create the format string to be used in `savetxt`.
id_fmt = '"%s"'   # The format of the id.
float_fmt = '%f'  # The floating point format.
fmt = id_fmt + b.shape[1] * (',' + float_fmt)

# Finally, save the data.
np.savetxt('ab.csv', data, fmt=fmt)

这是输出文件的内容:

"A001",0.000000,0.062500,0.125000,0.187500
"A019",0.250000,0.312500,0.375000,0.437500
"A344",0.500000,0.562500,0.625000,0.687500
"A742",0.750000,0.812500,0.875000,0.937500

【讨论】:

    【解决方案3】:

    如果您不需要将数组保存为纯文本,我也会考虑使用np.savez,这将允许您将两个数组保存在一个二进制文件中。通过savez_compressed 还提供压缩版本。就个人而言,我经常使用 h5py 将多个数组保存到 hdf5,但是np.savez 提供了一个简单的接口,该接口是 numpy 内置的,因此不需要任何额外的依赖项。

    import numpy as np
    a = np.random.randint(0, 100, 10)
    b = np.random.rand(10, 3)
    np.savez('data.npz', a=a, b=b)
    
    # Now load the data back in
    data = np.load('data.npz')
    
    a_loaded = data['a']
    b_loaded = data['b']
    
    In [9]: a_loaded.dtype
    Out[9]: dtype('int64')
    
    In [10]: b_loaded.dtype
    Out[10]: dtype('float64')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-10
      • 2017-04-05
      • 2023-04-05
      • 2018-12-02
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 2019-03-18
      相关资源
      最近更新 更多