Pandas中奇怪的索引行为

时间:2013-12-27 17:22:49

标签: python pandas

我在考虑最近项目中可能由pandas中的非唯一索引引起的潜在问题,所以我开始玩一些场景来看看会发生什么。在这样做时,我偶然发现了以下奇怪的行为:

In [1]: import pandas as pd

In [2]: pd.version.version
Out[2]: '0.12.0'

In [3]: df1 = pd.DataFrame(range(10), index=[1, 2]*5)

In [4]: df2 = pd.DataFrame(range(10), index=range(5)*2)

In [5]: df1
Out[5]: 
   0
1  0
2  1
1  2
2  3
1  4
2  5
1  6
2  7
1  8
2  9

In [6]: df2
Out[6]: 
   0
0  0
1  1
2  2
3  3
4  4
0  5
1  6
2  7
3  8
4  9

如果我将df2的索引传递给df1的索引器,我会得到一些意想不到的结果(用箭头表示)

In [7]: df1.ix[df2.index]
Out[7]: 
              0
0           NaN
1  2.000000e+00
1  4.000000e+00
1  6.000000e+00
1  8.000000e+00
1  1.000000e+00 <---
2  3.000000e+00
2  5.000000e+00
2  7.000000e+00
2  9.000000e+00
2  0.000000e+00 <---
3           NaN
4           NaN
0           NaN
1  8.000000e+00
1  1.000000e+00 <---
1  3.000000e+00 <---
1  5.000000e+00 <---
1  7.000000e+00 <---
2  9.000000e+00 
2  3.636673e+17 <---
2  4.020594e+17 <---
2  3.628229e+17 <---
2  2.171412e+18 <---
3           NaN
4           NaN

不仅DataFrame中没有值,而且每个索引关联的一些值都是错误的/意外的;与1关联的值应为0,2,4,6和8,与2关联的值应为1,3,5,7和9.我认为这可能有与DataFrame.ix接受位置索引或标签有关,但同样的事情发生在DataFrame.loc

In [10]: df1.loc[df2.index]
Out[10]: 
              0
0           NaN
1  2.000000e+00
1  4.000000e+00
1  6.000000e+00
1  8.000000e+00
1  1.000000e+00
2  3.000000e+00
2  5.000000e+00
2  7.000000e+00
2  9.000000e+00
2  0.000000e+00
3           NaN
4           NaN
0           NaN
1  8.000000e+00
1  1.000000e+00
1  3.000000e+00
1  5.000000e+00
1  7.000000e+00
2  9.000000e+00
2  3.625411e+17
2  3.996824e+17
2  4.009981e+17
2  3.636670e+17
3           NaN
4           NaN

我多次重新运行此方案,并且意外值始终出现在同一位置,但可能是不同的值。为什么会发生这种情况,为什么不提出异常呢?我在文档中找不到解释,这在我工作的32位Windows系统和64位Linux上都会发生 系统在家里。我正在使用numpy 1.8.0,顺便说一句。

1 个答案:

答案 0 :(得分:1)

重复索引的重复索引在0.12中有所突破。这是0.13的结果。您的结果是一些内部例程访问非初始化内存的结果(因此返回的'值'在运行之间可能不一致 - 因此它是一个错误)。

你必须真正考虑你要求大熊猫做什么。

您所说的是根据您提供的df2.index的值进行查找,并在df1的索引中找到它们。

0,3,4不在df1的索引中,因此它们被标记为nan(因为它们被指定两次,所以每次都会得到nan两次)。值12匹配,每次匹配时都会得到匹配值(并且每次匹配都会得到多个值)。

In [13]: df1.ix[df2.index]
Out[13]: 
    0
0 NaN
1   0
1   2
1   4
1   6
1   8
2   1
2   3
2   5
2   7
2   9
3 NaN
4 NaN
0 NaN
1   0
1   2
1   4
1   6
1   8
2   1
2   3
2   5
2   7
2   9
3 NaN
4 NaN

[26 rows x 1 columns]

您可能正在寻找这种位置索引。您提供的值是结果的locations(并且不关心标签)。这适用于0.12和0.13 FYI。

In [14]: df1.iloc[df2.index]
Out[14]: 
   0
1  0
2  1
1  2
2  3
1  4
1  0
2  1
1  2
2  3
1  4

[10 rows x 1 columns]

重复重复索引非常棘手。如果你有一个替代解决方案,它提供了某些属性(例如索引器的顺序必须保留在输出中,你需要保证匹配所有重复项),我们很乐意听到它。