更改数据帧索引后,pandas版本0.16.0所有值都变为NaN

时间:2015-04-17 18:28:44

标签: python pandas ipython

我正在使用ipython笔记本,并且跟随pandas cookbook示例发布0.16.0。当我在第237页时遇到麻烦。我做了一个像这样的数据框

from pandas import *
data1=DataFrame({'AAA':[4,5,6,7],'BBB':[10,20,30,40],'CCC':[100,50,-30,-50]})

然后,我这样做,试图改变索引:

df=DataFrame(data=data1,index=(['a','b','c','d']))

但我得到的是一个数据帧,所有值都是NaN! 任何人都知道为什么以及如何解决它? 我也尝试使用set_index函数,它给了我错误。

非常感谢! enter image description here

3 个答案:

答案 0 :(得分:4)

如果要更改索引,请使用reindex或直接指定索引:

In [5]:

data1=pd.DataFrame({'AAA':[4,5,6,7],'BBB':[10,20,30,40],'CCC':[100,50,-30,-50]})
print(data1)
df=pd.DataFrame(data=data1)
df.index = ['a','b','c','d']
df
   AAA  BBB  CCC
0    4   10  100
1    5   20   50
2    6   30  -30
3    7   40  -50
Out[5]:
   AAA  BBB  CCC
a    4   10  100
b    5   20   50
c    6   30  -30
d    7   40  -50

我不知道这是不是一个错误,但是如果你做了以下情况那么它会起作用:

In [7]:

df=pd.DataFrame(data=data1.values,index=(['a','b','c','d']))
df
Out[7]:
   0   1    2
a  4  10  100
b  5  20   50
c  6  30  -30
d  7  40  -50

因此,如果您将数据分配给值而不是df本身,那么df不会尝试与传入的索引对齐

修改

在这里单步执行代码后,问题是它使用传递的索引来重新索引df,我们可以通过执行以下操作来重现此行为:

In [46]:

data1 = pd.DataFrame({'AAA':[4,5,6,7],'BBB':[10,20,30,40],'CCC':[100,50,-30,-50]})
data1.reindex_axis(list('abcd'))
Out[46]:
   AAA  BBB  CCC
a  NaN  NaN  NaN
b  NaN  NaN  NaN
c  NaN  NaN  NaN
d  NaN  NaN  NaN

这是因为它进入df构造函数检测到它是BlockManager的实例并尝试构造一个df:

单步执行代码我看到它到达frame.py:

        if isinstance(data, BlockManager):
        mgr = self._init_mgr(data, axes=dict(index=index, columns=columns),
                             dtype=dtype, copy=copy)

然后在generic.py中结束:

119         def _init_mgr(self, mgr, axes=None, dtype=None, copy=False):
120             """ passed a manager and a axes dict """
121             for a, axe in axes.items():
122                 if axe is not None:
123                     mgr = mgr.reindex_axis(
124  ->                     axe, axis=self._get_block_manager_axis(a), copy=False)

现在已发布issue关于此

的信息

更新这是预期的行为,如果您传递索引,那么它将使用此索引重新索引传入的df,来自@Jeff

  

这是已定义的行为,用于将提供的输入重新索引到   传递索引和/或列。

参见相关的Issue

答案 1 :(得分:2)

EdChum对使用reindex的建议是完全正确的,但我认为这里发生的是当您使用DataFrame作为data参数的参数时,它在创建时使用整个现有的 DataFrame new DataFrame。

如果您想要完成所需的工作,则需要显式提供实际数据的DataFrame类(而不是另一个DataFrame中包含的数据)。您可以使用data1.values执行此操作。你还必须明确地给类提供列名,所以它们都是这样的:

In [1]: pd.DataFrame(data=data1.values,columns=data1.columns,index=(['a','b','c','d']))

Out[1]: 
   AAA  BBB  CCC
a    4   10  100
b    5   20   50
c    6   30  -30
d    7   40  -50

答案 2 :(得分:1)

  

也尝试使用set_index函数,它给了我错误。

为什么会发生这种情况? set_index用于使用一个或多个现有列来设置索引。因此,data1.set_index('a')会产生Key Error因为a不是data1中的列,而data1.set_index['AAA']会产生

     BBB  CCC
AAA          
4     10  100
5     20   50
6     30  -30
7     40  -50

其他两个答案回答了Q的其余部分。