这是我为 Pandas 的 DataFrame 版本编写的
dput
,它是生成可重复报告的标准 R 工具。对于更复杂的数据框架可能会出现问题,但在简单情况下似乎可以胜任:
import pandas as pd
def dput(x):
if isinstance(x,pd.Series):
return "pd.Series(%s,dtype='%s',index=pd.%s)" % (list(x),x.dtype,x.index)
if isinstance(x,pd.DataFrame):
return "pd.DataFrame({" + ", ".join([
"'%s': %s" % (c,dput(x[c])) for c in x.columns]) + (
"}, index=pd.%s)" % (x.index))
raise NotImplementedError("dput",type(x),x)
现在,
df = pd.DataFrame({'a':[1,2,3,4,2,1,3,1]})
assert df.equals(eval(dput(df)))
du = pd.get_dummies(df.a,"foo")
assert du.equals(eval(dput(du)))
di = df
di.index = list('abcdefgh')
assert di.equals(eval(dput(di)))
请注意,这会产生比DataFrame.to_dict
更冗长的输出,例如:
pd.DataFrame({
'foo_1':pd.Series([1, 0, 0, 0, 0, 1, 0, 1],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
'foo_2':pd.Series([0, 1, 0, 0, 1, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
'foo_3':pd.Series([0, 0, 1, 0, 0, 0, 1, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
'foo_4':pd.Series([0, 0, 0, 1, 0, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1))},
index=pd.RangeIndex(start=0, stop=8, step=1))
对比
{'foo_1': {0: 1, 1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 0, 7: 1},
'foo_2': {0: 0, 1: 1, 2: 0, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0},
'foo_3': {0: 0, 1: 0, 2: 1, 3: 0, 4: 0, 5: 0, 6: 1, 7: 0},
'foo_4': {0: 0, 1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}}
对于上面的du
命令,它可以保留列类型。例如,在上面的测试用例中,
请注意,此处的翻译不包含原始内容,只是对需要翻译的文本进行了翻译。
du.equals(pd.DataFrame(du.to_dict()))
==> False
因为 du.dtypes
是 uint8
,而 pd.DataFrame(du.to_dict()).dtypes
则是 int64
。
df.head(N).to_dict()
是一个不错的选择,其中N
是一个合理的数字。如果添加漂亮的换行符到输出中会得到额外的加分。对于时间戳,通常只需要在代码顶部添加from pandas import Timestamp
即可。 - Paul H