CSV 数据文件,其中写入"bytearray(...)"



我有一个csv文件,其中有两列,例如:

1621324695.083352,bytearray(b'x00x00x14Gx00x00nxfe')

第一个值是时间戳,另一个值是数据。

我的问题是,当我尝试用pd.read_csv()读取文件时,bytearray的值会变成字符串。有没有办法告诉python它已经是bytearray值了?

当我使用函数bytearray()时,它输出:bytearray(bytearray(b'...'))

在该文件中没有字节数组,只有它的文本表示(纯文本(。我们需要从中重新构建字节数组

要将像"bytearray(b'x00x00x14Gx00x00nxfe')"这样的字符串转换为真正的字节数组,第一个想法通常是使用eval,但有充分的理由尽可能避免使用eval

我们可以简单地从字符串中提取参数,处理其中的转义序列(如x00n(,并将结果传递给bytearray(),以创建最终对象。

要提取参数,请使用例如正则表达式。如果格式是固定的,简单的工具就可以了。

转义序列可以使用'unicode-escape'解码器取消转义,但我们必须从字符串转换为字节。latin1只是8位ASCII的名称,即字节数组使用的0-255值。

一个简单的演示:

inp = r"bytearray(b'x00x00x14Gx00x00nxfe')"
if inp.startswith("bytearray(b'") and inp.endswith("')"):
arg = inp[12:-2]   # strip bytearray(b' and '), leave the string in between
unesc = arg.encode('latin1').decode('unicode-escape')
ba = bytearray(unesc, 'latin1')
print(f"result: {ba!r}")
else:
print("parse error!")

ba是实字节数组,其表示repr(ba)等于inp

如果您控制csv的创建,那么在将字节数组写入csv时,最好对其进行base64编码,然后在数据帧中解码。

这种方法通常比字符串化二进制对象要好,后者通常需要在其他应用程序使用二进制对象时进行破解。此外,如果使用-bb标志执行Python,字符串化字节将引发异常。Base64编码通常用于在文本环境中对二进制数据进行编码。

首先,让我们制作一些二进制数据

import base64
import csv
import io
import zlib
import pandas as pd
# Create some binary data
bas = [bytearray(zlib.compress(bytearray(w.encode('ascii')))) for w in ['hello', 'goodbye']]
print(bas)

输出:

[bytearray(b'xx9cxcbHxcdxc9xc9x07x00x06,x02x15'),
bytearray(b'xx9cKxcfxcfOIxaaLx05x00x0bxaax02xea')]

现在将其写入内存中的csv(或创建csv文件,为了方便起见,我们在这里使用缓冲区(,应用base64编码

buf = io.StringIO()
writer = csv.writer(buf)
writer.writerow(['id', 'binary_data'])
for i, ba in enumerate(bas):
# Base64-encode the binary data and decode from bytes to str
encoded = base64.b64encode(ba).decode('ascii')
writer.writerow([i, encoded])
buf.seek(0)

将csv读取到数据帧中

# Read the csv into a dataframe
df = pd.read_csv(buf)
print(df)

输出:

id           binary_data
0   0  eJzLSM3JyQcABiwCFQ==
1   1  eJxLz89PSapMBQALqgLq

现在从base64解码以获得二进制数据

df['binary_data'] = df['binary_data'].apply(lambda cell: base64.b64decode(cell))
print(df)

输出

id                                       binary_data
0   0    b'xx9cxcbHxcdxc9xc9x07x00x06,x02x15'
1   1  b'xx9cKxcfxcfOIxaaLx05x00x0bxaax02xea'

我们得到的是bytes而不是bytearray,但这通常并不重要——这两种类型基本上是可互换的。

最新更新