pandas 版本 0.16.0 更改数据帧索引后所有值变为 NaN
pandas version 0.16.0 after changing dataframe index all values become NaN
我正在使用 ipython 笔记本并遵循 pandas 食谱示例版本 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 函数,但它给了我错误。
非常感谢!
如果要更改索引,请使用 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 已经发布
Update 这是预期的行为,如果您传递索引,那么它将使用该索引重新索引来自 @Jeff
的传入 df
This is the defined behavior, to reindex the provided input to the
passed index and/or columns .
查看相关内容Issue
EdChum 对使用 reindex 的建议完全正确,但我认为这里发生的事情是,当您使用 DataFrame 作为数据参数的参数时,它使用整个 existing 创建 new DataFrame 时的 DataFrame。
如果你想完成你正在做的事情,你需要显式地向 DataFrame class 提供实际的 数据 (不是包裹在另一个数据中的数据)数据框)。您可以使用 data1.values 来执行此操作。您还必须显式地给 class 列名,所以结果都是这样的:
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
also tried to use set_index function, and it gave me errors.
为什么会这样? set_index
是为了使用一个或多个 existing 列来设置索引。所以 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
其他两个答案回答了问题的其余部分。
我正在使用 ipython 笔记本并遵循 pandas 食谱示例版本 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 函数,但它给了我错误。
非常感谢!
如果要更改索引,请使用 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 已经发布
Update 这是预期的行为,如果您传递索引,那么它将使用该索引重新索引来自 @Jeff
的传入 dfThis is the defined behavior, to reindex the provided input to the passed index and/or columns .
查看相关内容Issue
EdChum 对使用 reindex 的建议完全正确,但我认为这里发生的事情是,当您使用 DataFrame 作为数据参数的参数时,它使用整个 existing 创建 new DataFrame 时的 DataFrame。
如果你想完成你正在做的事情,你需要显式地向 DataFrame class 提供实际的 数据 (不是包裹在另一个数据中的数据)数据框)。您可以使用 data1.values 来执行此操作。您还必须显式地给 class 列名,所以结果都是这样的:
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
also tried to use set_index function, and it gave me errors.
为什么会这样? set_index
是为了使用一个或多个 existing 列来设置索引。所以 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
其他两个答案回答了问题的其余部分。