python的多维数组和字节串(或字符串)之间转换(数据传输)

在进行数据传输的时候我们可能会遇到各种数据类型,而传输只支持字节串类型(bytes类型)的数据,因此我们需要想办法将各种数据类型都转换为字节串类型或者字符串类型(字符串类型可以通过encode转成字节串)

这次的讨论是如何将数组类型(ndarray类型)转换为字节串,这里给出两种方案:

一、通过tostring和fromstring转换
tostring会将数组直接转换成字节串,并且会损失类型信息(dtype)和维度信息(shape),因此在实际传输中,除了把字节串传输过去外,还需要把数组的dtype和shape传输过去

import numpy as np

a1 = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[11,22,33],[44,55,66],[77,88,99]],[[111,222,333],[444,555,666],[777,888,999]]])

a1_dtype = str(a1.dtype)
a1_shape = str(a1.shape)
print(a1.dtype) # 说明a1的dtype为int32
print(a1.shape) # 说明维度信息为(3,3,3)
s = a1.tostring()
print(type(s)) # 可知这里直接将数组转换成了字节串bytes

# 下面三句效果一样
# a2 = np.fromstring(s,dtype=np.int32).reshape((3,3,3))
# a2 = np.fromstring(s,dtype=getattr(np,str(a1.dtype))).reshape(a1.shape)
a2 = np.fromstring(s,dtype=getattr(np,a1_dtype)).reshape(eval(a1_shape))

print(a2) # 转换成功

二、将数组转换为列表,列表再转换为字符串,再用eval取出列表

使用numpy里的tolist()方法可以彻底将数组转换成列表,而python中的eval()函数能从字符串中读取出list类型的数据,将整个字符串执行一遍并返回其结果

import numpy as np

a1 = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[11,22,33],[44,55,66],[77,88,99]],[[111,222,333],[444,555,666],[777,888,999]]])
my_list1 = a1.tolist()
print(my_list1)
s = "np.array({})".format(my_list1)
a2 = eval(s)
print(a2)

这里对比一下tolist()和list()函数,tolist()函数能将数组彻底转换成列表,并且保留维度信息,而list()不行,list()只会讲数据转换成一维列表,列表里面的元素又是数组(该数组还是原数组转换成列表后再转换过来的数组)
示例:

import numpy as np

a1 = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[11,22,33],[44,55,66],[77,88,99]],[[111,222,333],[444,555,666],[777,888,999]]])
my_list2 = list(a1)
print(my_list2)

结果:

[array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]]), array([[11, 22, 33],
       [44, 55, 66],
       [77, 88, 99]]), array([[111, 222, 333],
       [444, 555, 666],
       [777, 888, 999]])]

而该列表也能转换回数组:

a2 = np.array(my_list2)
print(a2)

但是将该列表转换为字符串后,eval无法识别出来

import numpy as np

a1 = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[11,22,33],[44,55,66],[77,88,99]],[[111,222,333],[444,555,666],[777,888,999]]])
my_list2 = list(a1)
print(my_list2)

s = str(my_list2)

a2 = np.array(eval(s)) # 报错
print(a2)

错误信息:

NameError: name 'array' is not defined

因此list()方法要慎用

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值