Python Pandas 如何从命令行读取 C++ 结构二进制文件
Posted
技术标签:
【中文标题】Python Pandas 如何从命令行读取 C++ 结构二进制文件【英文标题】:How Python Pandas can read C++ struct binary from command line 【发布时间】:2020-08-27 13:41:50 【问题描述】:我有一个名为SomeData
的自定义结构的std::vector
:
struct SomeData
float a;
bool b;
int c;
;
我通过reinterpet_cast
-ing 将对象写入字节的二进制文件:
myfile.write(reinterpret_cast<const SomeData*>(&obj), sizeof(obj));
Python 用户想要从 Linux 命令行将此数据加载到 Pandas。然而,显然 Pandas 并不知道 SomeData
结构是什么样的。
Python 用户有什么方法可以将二进制文件读入 Pandas? PyBind 可以在这里提供帮助吗 - 一个包装器或其他东西?
pandasTable = wrapperToConvertSomeDataToPandas()
(我真的更愿意避免使用 Parquet)
【问题讨论】:
python中读取数据的方式有很多种,看数据是什么,请提供minimal reproducible example 这个数据怎么写成二进制,你用什么序列化方法?当然,PyBind“可以”提供帮助,解决它有多种可能性。目前我认为你的问题不容易回答。 @pptaszni 嗨,我刚刚更新了我的问题。我将 C++ 对象重新解释为字节。很高兴修改问题以使其更容易回答。SomeData
包含哪些字段?如果它包含指针或 C++ 对象,那么您的字节表示在您的 C++ 程序中是没有意义的。
@Botje 没有指针或字符串,假设只有浮点数、布尔值和整数
【参考方案1】:
我建议您切换到自描述的序列化格式,例如 AVRO。这只会将负担放在 C++ 程序上;你的 Python 代码只接收一个对象列表。现在可能看起来很笨拙,但以后会为您节省时间和痛苦。
【讨论】:
我刚刚回复了您的评论问题。知道它只是原始类型,您的答案是否相同? 是的。序列化是一个已解决的问题,您应该使用 AVRO(或任何其他常见的序列化库,如 protobufs 或 Thrift 甚至 JSON)并将时间花在实际的业务问题上。【参考方案2】:您应该使用一些序列化库(例如protobuf),正如上一个答案中已经建议的那样。但是,如果您真的希望继续使用reinterpret_cast
解决方案,您可以编写一个知道您的SomeData
结构、正确解释二进制文件并返回Pandas DataFrame 的python 函数。例如:
import struct
import pandas as pd
def readBinaryData(myFile):
d = 'float': [], 'bool': [], 'int': []
buff = myFile.read(12)
while (len(buff) == 12):
d['float'].append(struct.unpack("f", buff[0:4])[0])
d['bool'].append(bool(struct.unpack("i", buff[4:8])[0]))
d['int'].append(struct.unpack("i", buff[8:12])[0])
buff = myFile.read(12)
return pd.DataFrame(data=d)
df = readBinaryData(open("output.bin", "rb"))
print(df)
可能的输出:
float bool int
0 1.1 True 1
1 2.2 False 2
2 3.3 False 3
这种方法的问题是您需要知道 C++ 数据类型的大小,这可能取决于实现。在我的情况下,SomeData
结构的大小是 12,而不是预期的 4 + 1 + 4 = 9 字节。出于这个原因bool(struct.unpack("i", buff[4:8])[0])
,因为结构填充。
然后根据您客户的要求,您可以将其分发为源代码或 python 包,或一些共享库。
【讨论】:
以上是关于Python Pandas 如何从命令行读取 C++ 结构二进制文件的主要内容,如果未能解决你的问题,请参考以下文章
Python中的pandas如何读取excel中指定单元格的值?