如何在Python3的HTTP服务器中保留DataFrame列的bytes对象?
解决Pandas Bytes列通过HTTP传输后无法恢复的问题
问题根源
CSV是纯文本格式,当Pandas将包含bytes对象的DataFrame导出为CSV时,会自动把bytes转为它的字符串表示(比如b'x\x9cd'变成"b'x\\x9cd'")。客户端读取CSV时,这部分内容会被识别为普通字符串,而非原始bytes对象,直接转换会导致多一层b''包裹,无法恢复原始二进制数据。
解决方案
方法1:用Pickle直接序列化整个DataFrame(最简单)
这种方法直接保留DataFrame的所有数据类型,无需额外处理列:
服务器端代码
import pickle import zlib # 序列化DataFrame并压缩 bytes_obj = zlib.compress(pickle.dumps(output)) self.wfile.write(bytes_obj)
客户端代码
import pickle import zlib import pandas as pd response = requests.get(url) response_bytes = response.content # 解压并反序列化还原DataFrame response_dataframe = pickle.loads(zlib.decompress(response_bytes))
方法2:将Bytes转为Base64字符串传输(兼容文本格式场景)
把二进制数据编码为Base64字符串,避免CSV对bytes的转义问题,同时保持CSV的文本可读性:
服务器端代码
import base64 import pandas as pd import zlib # 将data列的bytes转为Base64字符串 output['data'] = output['data'].apply(lambda b: base64.b64encode(b).decode('utf-8')) # 导出CSV并压缩 bytes_obj = zlib.compress(output.to_csv(index=False).encode()) self.wfile.write(bytes_obj)
客户端代码
import base64 import pandas as pd import zlib import io response = requests.get(url) response_bytes = response.content # 解压并读取CSV response_dataframe = pd.read_csv(io.BytesIO(zlib.decompress(response_bytes))) # 将Base64字符串转回原始bytes response_dataframe['data'] = response_dataframe['data'].apply(lambda s: base64.b64decode(s))
方法3:使用二进制存储格式(如Parquet,适合大数据场景)
Parquet是高效的二进制列存格式,能完美保留数据类型,同时压缩效率更高:
服务器端代码
import zlib import io import pandas as pd # 将DataFrame写入Parquet字节流 parquet_buffer = io.BytesIO() output.to_parquet(parquet_buffer, index=False) parquet_buffer.seek(0) # 压缩后发送 bytes_obj = zlib.compress(parquet_buffer.read()) self.wfile.write(bytes_obj)
客户端代码
import zlib import io import pandas as pd response = requests.get(url) response_bytes = response.content # 解压并读取Parquet parquet_buffer = io.BytesIO(zlib.decompress(response_bytes)) response_dataframe = pd.read_parquet(parquet_buffer)
内容的提问来源于stack exchange,提问作者Sam11
相关产品推荐
相关产品推荐

