如何在pandas DataFrame中存储行的名称和列的索引?

5 人关注

我有一个 DataFrame 名为 行和列的索引。

import numpy as np
import pandas as pd
I = pd.Index(["a", "b", "c", "d"], name="rows")
C = pd.Index(["col0", "col1", "col2"], name="cols")
df = pd.DataFrame(data=np.random.rand(4, 3),
                  index=I,
                  columns=C)

我试着用几种格式(Excel、CSV)来存储它,但当重新阅读文件时,名称就丢失了(也许我错过了一些选项)。替换代码2】可以工作,但它被标记为实验性的,所以我宁愿暂时避免它。我也希望避免pickle。有什么方法(格式和选项)来存储这两个索引的名称吗?

EDIT: 我知道如何用pandas写和读CSV。问题是要保存列索引和行索引的名称。

2 个评论
第一个版本的代码是错误的(名字没有保存)。对此我很抱歉。
访问和导出索引和列的名称完全不是问题。然而,我正在考虑一种适当的方法来导入导出的数据,因为这只在使用多索引时才有意义。但是,你不需要使用多索引来正确访问你的数据。
python
pandas
Mathieu Dubois
Mathieu Dubois
发布于 2016-01-28
4 个回答
Stop harming Monica
Stop harming Monica
发布于 2016-01-28
已采纳
0 人赞同

你可以使用hdf。

import numpy as np
import pandas as pd
I = pd.Index(["a", "b", "c", "d"], name="rows")
C = pd.Index(["col0", "col1", "col2"], name="columns")
df = pd.DataFrame(data=np.random.rand(4,3), index=I, columns=C)
print(df)
columns      col0      col1      col2
a        0.098497  0.918954  0.642800
b        0.168266  0.678434  0.455059
c        0.434939  0.244027  0.599400
d        0.877356  0.053085  0.182661
df.to_hdf('test.hdf', 'test')
print(pd.read_hdf('test.hdf'))
columns      col0      col1      col2
a        0.098497  0.918954  0.642800
b        0.168266  0.678434  0.455059
c        0.434939  0.244027  0.599400
d        0.877356  0.053085  0.182661
    
似乎是完美的交易!
albert
albert
发布于 2016-01-28
0 人赞同

你可以用以下方法将数据框架导出到csv文件中 .to_csv() 并用以下方式将其读回 .read_csv() .我扩展了你已有的代码,如下所示。

#!/usr/bin/env python3
# coding: utf-8
import numpy as np
import pandas as pd
I = pd.Index(["a", "b", "c", "d"], "rows")
C = pd.Index(["col0", "col1", "col2"], "cols")
df = pd.DataFrame(data=np.random.rand(4,3), index=I, columns=C)
# export DataFrame to csv
df.to_csv('out.csv')
# set index_col in order to read first column as indices
df_in = pd.read_csv('out.csv', index_col=0)

所以DataFrame df看起来是这样的。

       col0      col1      col2
a  0.590016  0.834033  0.535310
b  0.421589  0.897302  0.029500
c  0.373580  0.109005  0.239181
d  0.473872  0.075918  0.751628

The csv-file out.csv looks like this:

,col0,col1,col2
a,0.5900160748408918,0.8340332218911729,0.5353103406507513
b,0.42158899389955884,0.8973015040807538,0.029500416731096046
c,0.37357951184145965,0.10900495955642386,0.2391805787788026
d,0.47387186813644167,0.07591794371425187,0.7516279365972057

读回的数据导致了DataFrame df_in,如下所示。

       col0      col1      col2
a  0.590016  0.834033  0.535310
b  0.421589  0.897302  0.029500
c  0.373580  0.109005  0.239181
d  0.473872  0.075918  0.751628

因此,df2df完全相同,这表明出口和所需的进口是按预期工作的。

编辑导出列和索引名称:

df.to_csv('out.csv', index_label=[df.index.name, df.columns.name])

然而,这使得重新导入有点困难,因为列名被添加为一个额外的列。通常情况下,这对多索引数据很有用,但在这里会导致一个额外的空列。

所以我建议只导出索引名称。

# export DataFrame to csv
df.to_csv('out.csv', index_label=df.index.name)
# set index_col in order to read first column as indices
df_in = pd.read_csv('out.csv', index_col=0)

这导致了df_in为。

          col0      col1      col2
a     0.442467  0.959260  0.626502
b     0.639044  0.989795  0.853002
c     0.576137  0.350260  0.532920
d     0.235698  0.095978  0.194151

我不知道为什么你需要导出索引和列的名称。如果你只是想访问行或列的名称,你可以像这样获得它们的标签。

column_labels = df.columns.get_values()
>>> array(['col0', 'col1', 'col2'], dtype=object)
index_labels = df.index.get_values()
>>> array(['a', 'b', 'c', 'd'], dtype=object)
    
我的代码包含一个错误(很抱歉):名字没有正确设置。我知道如何保存在CSV中。问题是要保存索引的名称。在你的代码中, df_in 的列索引将不会被设置。
我也尝试过播放 index_label ,但没有成功(正如你所提到的,它很难重读)。我不认为CSV文件能正确处理这个问题。我希望Excel能工作,但据我所知,它不能。
你需要这些名字做什么?
好吧,我不需要这些名字,但有时拥有它们是很方便的(特别是对于多指标或复杂的df)。这是我设置它们的主要原因。
我看了你的答案,但这不是我想要的(我只想存储名字,不想访问值)。@Goyo的回答提供了一个基于HDF格式的简单答案。
Borja
Borja
发布于 2016-01-28
0 人赞同

你这里的DataFrame是否真的有索引名称?在我的电脑上,我需要写

I = pd.Index(["a", "b", "c", "d"], name="rows")
I = pd.Index(["a", "b", "c", "d"], "rows")

来实际分配这个名字。然后使用df.to_csv()和pd.read_csv(),索引名确实被保留了(在csv中,索引名只是像另一列一样被保存)。

如果这不起作用,你是否需要能够用Python以外的程序打开它?如果不需要,你可以使用 pickle,它应该不会影响到这个对象。

import pickle
pickle.dump(df, open("File.pickled", "wb"))
df_read = pickle.load(open("File.pickled", "rb"))

EDIT:如果你想在to_csv()中也保留列索引的名称,你可以做以下的破解。

用(将列索引转换为行,因此将其列索引名称设置为行索引值)保存。

df.T.reset_index().T.to_csv("DataFrame.csv")

然后用这两个中的任何一个来读,第一个(非常)稍快。

df_read = pd.read_csv("DataFrame.csv", index_col=0)
df_read.columns = df_read.loc['cols']
df_read = df_read.drop('cols', axis=0)
df_read = pd.read_csv("DataFrame.csv", index_col=0)
df_read = df_read.T.set_index('cols').T
    
哎呀!刚刚意识到...谢谢,我会纠正这个问题。然而,问题是当你对列和行都有一个名称时。
哼,我也希望能避免 pickle
@MathieuDubois 使用pickle会同时保存列和行的名称,但如果你想避免它,你可以在保存到CSV之前将列索引设置为行。我已经用相应的代码更新了我的答案。
ehhh
ehhh
发布于 2016-01-28
0 人赞同

df.to_csv 中的 header=True (用于列名)和 index=True (用于索引值)应该可以做到这一点。文档中说,两者默认都是 True 。然而,你将不得不在加载后手动设置索引,它被作为一个普通的列加载。为此,我给索引添加了一个名字。

import numpy as np
import pandas as pd
# your code:
I = pd.Index(["a", "b", "c", "d"], "rows")
C = pd.Index(["col0", "col1", "col2"], "cols")
df = pd.DataFrame(data=np.random.rand(4, 3),
                  index=I,
                  columns=C)
# name the index
I.name = 'index'
print "original:"
print df
print ""
df.to_csv("~/test.csv", index=True, header=True)
df2 = pd.read_csv("~/test.csv").set_index('index')
print "read from disk:"
print df2
print ""

Output:

original:
           col0      col1      col2
index                              
a      0.455378  0.830872  0.495953
b      0.707146  0.832009  0.112540
c      0.894997  0.156364  0.521047
d      0.775462  0.482554  0.578177
read from disk:
           col0      col1      col2
index