【问题标题】:Trying to strip b' ' from my Numpy array's savetxt() representation试图从我的 Numpy 数组的 savetxt() 表示中删除 b' '
【发布时间】:2014-12-16 18:17:44
【问题描述】:

所以我觉得这是一个非常愚蠢的问题。

我从一个文件创建一个数组:

A1=np.loadtxt(file, dtype='a100')

我想在完成处理后将该数组写入另一个文件:

np.savetxt("Test.txt", A1, fmt=%s, delimiter=',')

为什么要写出b'string'?我想我知道它是以字节的形式写出来的,但是对于我的一生,我不知道如何在没有 b'' 的情况下写出来。

我知道这可能是我忽略的非常容易的事情!

【问题讨论】:

标签: python python-3.x numpy


【解决方案1】:

A1 作为字节串数组加载。 Python3 默认使用 unicode 字符串,因此通常在它们前面加上 'b'。这对于print 来说是正常的。我有点惊讶它在文件写入期间也是如此。

无论如何,这似乎可以解决问题:

A2=np.array([x.decode() for x in A1])
np.savetxt("Test.txt", A2, fmt='%s', delimiter=',')

A2 的 dtype 类似于 dtype='<U100'


我的测试数组是:

array([b'one.com', b'two.url', b'three.four'], dtype='|S10')

从一个简单的文本文件加载:

one.com
two.url
three.four

.decode 是一个字符串方法。 [x.decode() for x in A1] 适用于简单的一维字节串数组。如果A1 是2d,则必须对所有元素进行迭代,而不仅仅是行。如果A1 是结构化数组,则必须将其应用于元素内的字符串。


另一种可能性是在加载期间使用转换器,因此您会得到一个 (unicode) 字符串数组

In [508]: A1=np.loadtxt('urls.txt', dtype='U',
    converters={0:lambda x:x.decode()})
In [509]: A1
Out[509]: 
array(['one.com', 'two.url', 'three.four'], dtype='<U10')
In [510]: np.savetxt('test0.txt',A1,fmt='%s')
In [511]: cat test0.txt
one.com
two.url
three.four

包含loadtxt 的库有几个转换器函数asbytesasbytes_nestedasstr。所以converters 也可以是:converters={0:np.lib.npyio.asstr}

genfromtxt 在没有 converters 的情况下处理这个问题:

 A1=np.genfromtxt('urls.txt', dtype='U')
 # array(['one.com', 'two.url', 'three.four'], dtype='<U10')

要理解为什么savetxt 保存我们想要的unicode 字符串,但附加b 用于字节字符串,我们必须查看它的代码。

np.savetxt(在 py3 上运行)本质上是:

fh = open(fname, 'wb')
X = np.atleast_2d(X).T
# make a 'fmt' that matches the columns of X (with delimiters)
for row in X:
    fh.write(asbytes(format % tuple(row) + newline))

查看两个示例字符串(str 和 bytesstr):

In [617]: asbytes('%s'%tuple(['one.two']))
Out[617]: b'one.two'

In [618]: asbytes('%s'%tuple([b'one.two']))
Out[618]: b"b'one.two'"

写入“wb”文件会删除b'' 的外层,留下字节串的内层。它还解释了为什么将字符串('plain' py3 unicode)作为 'latin1' 字符串写入文件。


你可以直接写一个字节串数组,不用savetxt。例如:

A0 = array([b'one.com', b'two.url', b'three.four'], dtype='|S10')
with open('test0.txt','wb') as f:
    for x in A0:
        f.write(x+b'\n')

cat test0.txt
    one.com
    two.url
    three.four

Unicode 字符串也可以直接写入,生成相同的文件:

A1 = array(['one.com', 'two.url', 'three.four'], dtype='<U10')
with open('test1.txt','w') as f:
    for x in A1:
        f.write(x+'\n')

此类文件的默认编码为encoding='UTF-8',与'one.com'.encode() 使用的相同。效果和savetxt一样:

with open('test1.txt','wb') as f:
    for x in A1:
        f.write(x.encode()+b'\n')

np.char 具有 .encode.decode 方法,它们似乎对数组的元素进行迭代操作。

因此

 np.char.decode(A1)   # convert |S10 to <U10, like [x.decode() for x in A1]
 np.char.encode(A1)   # convert <U10 to |S10

这适用于多维数组

 np.savetxt('testm.txt',np.char.decode(A_bytes[:,None][:,[0,0]]),
     fmt='%s',delimiter=',  ')

对于结构化数组,np.char.decode 必须单独应用于每个字符字段。

【讨论】:

  • 我试过你的,这是我得到的错误:'numpy.void' object has no attribute 'decode'
  • A1 的 dtype 是什么?如果xnumpy.void,我猜它是结构化数组的一个元素。 .decode 是一个 string 方法。
猜你喜欢
  • 2019-03-24
  • 1970-01-01
  • 2019-04-03
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
相关资源
最近更新 更多