python – 做差异时pandas.Series名称的作用

我有两个pandas.Series对象,比如a和b,具有相同的索引,当执行差异时a – b我得到错误

ValueError:具有多个元素的数组的真值是不明确的.使用a.any()或a.all()

我不明白从哪里来.

系列a是作为DataFrame的一个片段获得的,其索引是MultiIndex,当我进行重命名时

a.name = 0

该操作工作正常(但如果我重命名为元组,我得到相同的错误).

不幸的是,我无法重现这种现象的最小例子(ad-hoc系列与名称元组的差异似乎工作正常).

有关为什么会发生这种情况的任何想法?

如果相关,pandas版本是0.22.0

编辑

错误的完整回溯:

----------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-15-e4efbf202d3c> in <module>()
----> 1 one - two

~/venv/lib/python3.4/site-packages/pandas/core/ops.py in wrapper(left, right, name, na_op)
    727 
    728         if isinstance(rvalues, ABCSeries):
--> 729             name = _maybe_match_name(left, rvalues)
    730             lvalues = getattr(lvalues, 'values', lvalues)
    731             rvalues = getattr(rvalues, 'values', rvalues)

~/venv/lib/python3.4/site-packages/pandas/core/common.py in _maybe_match_name(a, b)
    137     b_has = hasattr(b, 'name')
    138     if a_has and b_has:
--> 139         if a.name == b.name:
    140             return a.name
    141         else:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

编辑2

有关如何获得a和b的更多细节:

>我有一个DataFrame df,其索引是multyindex(year,id_)
>我有一个系列因子,其索引是df的列(类似于列的标准偏差)
>然后:

tmp = df.loc[(year, id_)]
a = tmp[factors != 0]
b = factors[factors != 0]
diff = a - b

并执行最后一行错误发生.

编辑3

如果我减少列,它也会继续发生:原始df有大约1000行和列,但减少到最后5行和列,问题仍然存在!

例如,通过做

df = df.iloc[-10:][df.columns[-5:]]
line = df.iloc[-3]
factors = factors[df.columns]
a = line[factors != 0]
b = factors[factors != 0]
diff = a - b

我一直得到同样的错误,而打印a和b我得到了

A:

end_bin_68.750_100.000    0.002413
end_bin_75.000_100.000    0.002614
end_bin_81.250_100.000    0.001810
end_bin_87.500_100.000    0.002313
end_bin_93.750_100.000    0.001609
Name: (2015, 10000030), dtype: float64

b:

end_bin_68.750_100.000    0.001244
end_bin_75.000_100.000    0.001242
end_bin_81.250_100.000    0.000918
end_bin_87.500_100.000    0.000659
end_bin_93.750_100.000    0.000563
Name: 1, dtype: float64

如果我手动创建具有这些相同值的df和因子(也在索引中),则不会发生错误.

编辑4

在调试时,当一个人到达函数_maybe_match_name时,获得以下内容:

ipdb> type(a.name)
<class 'tuple'>

ipdb> type(b.name)
<class 'numpy.int64'>

ipdb> a.name == b.name
a = end_bin_68.750_100.000    0.002413
end_bin_75.000_100.000    0.002614
end_bin_81.250_100.000    0.001810
end_bin_87.500_100.000    0.002313
end_bin_93.750_100.000    0.001609
Name: (2015, 10000030), dtype: float64
b = end_bin_68.750_100.000    0.001244
end_bin_75.000_100.000    0.001242
end_bin_81.250_100.000    0.000918
end_bin_87.500_100.000    0.000659
end_bin_93.750_100.000    0.000563
Name: 1, dtype: float64

ipdb> (a.name == b.name)
array([False, False])

编辑5

最后我得到了一个最小的例子:

a = pd.Series([1, 2, 3])
a.name = np.int64(13)

b = pd.Series([4, 5, 6])
b.name = (123, 789)

a - b

这会给我带来错误,np .__ version__ == 1.14.0和pd .__ version__ == 0.22.0

最佳答案 当两个pandas Series之间进行操作时,它会尝试为生成的Series提供一个名称.

s1 = pd.Series(np.random.randn(5))
s2 = pd.Series(np.random.randn(5))
s1.name = "hello"
s2.name = "hello"
s3 = s1-s2
s3.name
>>> "hello"

如果名称不相同,则生成的Series没有名称.

s1 = pd.Series(np.random.randn(5))
s2 = pd.Series(np.random.randn(5))
s1.name = "hello"
s2.name = "goodbye"
s3 = s1-s2
s3.name
>>> 

这是通过将系列名称与函数_maybe_match_name()进行比较来完成的,而不是GitHub上的here.

比较运算符在您的情况下明显地比较了一个具有元组的数组,这是不可能的(我无法重现错误),并引发ValueError异常.

我猜这是一个错误,奇怪的是np.int64(42)==(“A”,“B”)不会为我引发异常.
但是我有一个来自numpy的FutureWarning:
FutureWarning:元素比较失败;返回标量,但将来会执行元素比较.

这让我觉得你使用的是最新的numpy版本(你是从GitHub上的master分支编译的?).

这个bug很可能会在下一个pandas发布中得到纠正,因为它是numpy行为未来发生变化的结果.

我的猜测是,最好的办法就是在进行操作之前重命名你的系列,因为你已经做了b.name = None,或者改变你的numpy版本(1.15.0works).

点赞