我从Python脚本中以字节格式向Elasticache Redis集群中写入一个float32数组,然后在Go脚本中从Elasticache中阅读字节(作为字符串)。如何将字节作为字符串转换回Go脚本中原始的float32数组?
Python示例:
import numpy as np
import redis
a = np.array([1.1, 2.2, 3.3], dtype=np.float32)
a_bytes = a.tobytes(order="C") #I have also tried order="F" with no luck
print(a_bytes) #Output: b'\xcd\xcc\x8c?\xcd\xcc\x0c@33S@'
redis_client = redis.cluster.RedisCluster(host=<elasticache config endpoint>, port=6379)
redis_client.mset_nonatomic({"key1": a_bytes})
字符串
下面是我在Go(playground)中尝试的一个例子。
package main
import (
"fmt"
"math"
"strconv"
)
func main() {
// aBytesStr is an example value retrieved from Elasticache
// aBytesStr is type string, not raw bytes
var aBytesStr string = "\xcd\xcc\x8c?\xcd\xcc\x0c@33S@"
aHex := fmt.Sprintf("%X", aBytesStr)
fmt.Println(aHex) // Output: CDCC8C3FCDCC0C4033335340
var aArr [3]float32
for i := 0; i < 3; i++ {
aHex1 := aHex[i*8 : i*8+8]
aParsed, err := strconv.ParseUint(aHex1, 16, 32)
if err != nil {
return
}
aArr[i] = math.Float32frombits(uint32(aParsed))
}
fmt.Println(aArr)
// Expected output: [1.1 2.2 3.3]
// Actual output [-4.289679e+08 -4.2791936e+08 4.17524e-08]
}
型
1条答案
按热度按时间jxct1oxe1#
你使用的示例代码是“转换十六进制,表示为字符串”;你有原始字节(我认为基于
aHex: CDCC8C3FCDCC0C4033335340
),所以直接转换更简单(虽然你可以将字节转换为十六进制字符串,然后转换,这样做只会增加不必要的工作/复杂性)。从this answer作图,我们得到(playground):
字符串
更新参考注解:
我将bytes-as-string转换为十六进制字符串,转换为[]bytes,转换为[] float 32。有没有一种方法可以直接将bytes-as-string转换为[]bytes?
我仍然有点困惑你收到什么,所以让我们通过这两种可能性的工作。
如果redis查询返回原始数据(字节)作为go字符串(即
"\xcd\xcc\x8c?\xcd\xcc\x0c@33S@"
),那么您可以将其转换为[]byte
(playground)型
如果redis返回一个包含ASCII(/UTF-8)表示的字符串(即
CDCC
=[]byte{0x41, 0x44, 0x43, 0x43}
),最简单的方法可能是使用encoding/hex来解码(playground)型
请注意,您原来的方法可以工作,但正如上面的评论中所指出的,您需要处理Endianness,以便以下工作(playground-您可以使其更有效,我的目的是为了清晰):
型
然而,这对代码运行的CPU做出了假设,这意味着前面的答案更可取。