为什么元组在保存到 csv 并重新加载数据帧后变成字符串 (pandas)?

Why do tuples become strings after saving to csv and reloading the dataframe (pandas)?

import pandas as pd
from random import random
from collections import namedtuple

Smoker    = namedtuple("Smoker", ["Female","Male"])
Nonsmoker = namedtuple("Nonsmoker", ["Female","Male"])

DF = dict() 
DF["A"] = [(Smoker(random(),random()), Nonsmoker(random(),random())) for t in range(3)]
DF["B"] = [(Smoker(random(),random()), Nonsmoker(random(),random())) for t in range(3)]
DF = pd.DataFrame(DF, index=["t="+str(t+1) for t in range(3)])

我有这个数据框,每个单元格都是两个命名元组的元组。在我将它保存到 csv 文件并重新加载之后,打印出来的结果看起来是一样的,但是每个单元格变成了一个 字符串 。它怎么发生的?每次获取相同的dataframe怎么办?

DF.to_csv("results.csv", index_label=False)
df = pd.read_csv('results.csv', index_col=0)

print(df)

for a,b in zip(df.A,df.B):
    print(type(a),type(b))

读取 csv 时获取元组的一种方法是使用 converters

例如:

import ast

df = pd.read_csv('results.csv', index_col=0, converters={"A": ast.literal_eval, 
                                                         "B": ast.literal_eval})

我相信这是预期的行为。由于 csv 是 text-base,当您将 object dtype 保存为 csv 时,自然的方式是使用字符串表示。所以 tuple((1,2)) 变成 "(1,2)".

现在,当您回读 csv 文件时,解释 "(1,2)" 的自然且安全的方式当然是字符串 '(1,2)',因为 Pandas 没有解析 tuple-valued 列的引擎。

TLDR,这是正常的预期行为。如果要使用 object dtype 保存和加载数据,则应使用二进制格式,例如 to_picklefrom_pickle 方法。