【发布时间】:2019-01-11 20:22:44
【问题描述】:
我实现了一个Serie 类来表示一系列数据及其标签。当我添加 Serie 对象和数字时,我得到了预期的输出。但是,当我对列表中的相同元素求和时,我收到以下错误消息:
TypeError:+ 不支持的操作数类型:“int”和“Serie”
玩具示例代码
作为一个玩具示例代码来理解我们可以使用的问题:
import pandas as pd
import numpy as np
class Serie(object):
def __str__(self):
s = "> SERIE " + str(self.tag) + ": \n"
s += str(self.data)
return s
def __init__(self, tag=None, data=pd.DataFrame()):
"""
Creates object Serie
@type tag: str
@param tag: Tag for the Serie
"""
self.tag = tag
self.data = data
def __add__(self, other):
if isinstance(other, int) or isinstance(other, float):
tag = str(other) + "+" + self.tag
serie = Serie(tag)
serie.data = self.data + other
else:
try:
tag = self.tag + "+" + other.tag
except:
print ("ERROR: You can't add to somehing that is not a Serie or a number." )
return None
serie = Serie(tag)
serie.data = self.data + other.data
return serie
s1 = Serie("fibonacci",pd.Series([1,1,2,3,5,8]))
s2 = Serie("2power",pd.Series(np.linspace(1,6,6)**2))
s3 = 10
sumSerie = s1+s2+s3
print sumSerie
这会按预期打印结果:
>>>
> SERIE 10+fibonacci+2power:
0 12.0
1 15.0
2 21.0
3 29.0
4 40.0
5 54.0
dtype: float64
在列表中使用对象总和时出错
但是当我运行以下几行时:
l = [s1,s2,s3]
sum(l)
我收到错误消息:
总和(升) 类型错误:+ 不支持的操作数类型:“int”和“Serie”
当我运行时显示相同的错误消息:
l2 = [s1,s2]
sum(l2)
但在l2 列表中没有int 变量。
问题
为什么会显示此错误消息?这很令人困惑,因为我能够对列表之外的对象求和。
我可以做些什么来实现列表中对象的总和吗?
编辑
按照 cmets 中的建议,我添加了 __radd__ 以正确重载 add 方法。所以我在Serie 类中添加了以下几行:
def __radd__(self,other):
return self.__add__(other)
然后总和起作用。但不如预期。
如果我运行以下代码:
>>> print sum(l)
我得到这个输出:
> SERIE 10+0+fibonacci+2power:
0 12.0
1 15.0
2 21.0
3 29.0
4 40.0
5 54.0
dtype: float64
这绝对不是我预期的那样。标签中有一个 +0 额外的。怎么会这样?但是,如果我使用我在回答 print np.array(l).sum() 中声明的选项,则结果是正确的。
编辑 2
正确重载 add 方法后,建议我使用以下方法按预期执行求和:
reduce(lambda a, b: a+b, l)
这种方法能够对列表使用sum 函数并获得正确的结果。
正如pault 在sum 方法中的cmets 中所述,“开始默认为0”,详见sum function's documentation。这就是为什么之前在标签中添加了额外的+0。
总之,我相信我会更喜欢使用 numpy.sum 函数的选项:
np.array(l).sum()
【问题讨论】:
标签: python pandas python-2.7 add series