为什么我们需要三种操作方式?
(我用乘法作为例子)
第一条路:
df['a'] * 5第二条路:
df['a'].mul(5)第三条路:
df['a'].__mul__(5)两个还不够吗,不需要一个mul,我在想它会不会像正常的方式,像一个整数
第一条路:
3 * 5第二条路:
(3).__mul__(5)但在一个内鬼的固定基地:
(3).mul(5)就会崩溃。
我只是好奇,为什么我们需要这么多的东西在潘达斯,这是相同的加法,减法和除法。
发布于 2019-04-19 04:34:49
*和mul做同样的事情,但是__mul__是不同的。
*和mul在委托给__mul__之前执行一些检查。有两件事你应该知道。
NotImplemented在无法处理其他操作数的情况下,类的NotImplemented返回一个特殊的单例值__mul__。这将告诉Python尝试__rmul__。如果这也失败了,则会引发泛型TypeError。如果直接使用__mul__,就不会得到这种逻辑。观察:
class TestClass:
def __mul__(self, other):
return NotImplemented
TestClass() * 1输出:
TypeError: unsupported operand type(s) for *: 'TestClass' and 'int'将此与以下内容进行比较:
TestClass().__mul__(1)输出:
NotImplemented这就是为什么通常情况下,您应该避免直接调用does (魔术)方法:您绕过Python所做的某些检查。
在尝试执行类似于Base() * Derived()的操作时,Derived从Base继承,您会希望首先调用Base.__mul__(Derived())。这可能会带来问题,因为Derived.__mul__更可能知道如何处理这种情况。
因此,当您使用*时,Python会检查右操作数的类型是否比左的派生得更多,如果是,则直接调用右操作数的__rmul__方法。
观察:
class Base:
def __mul__(self, other):
print('base mul')
class Derived(Base):
def __rmul__(self, other):
print('derived rmul')
Base() * Derived()输出:
derived rmul注意,尽管Base.__mul__不返回NotImplemented,并且可以清楚地处理Derived类型的对象,但是Python甚至没有首先查看它;它立即将它委托给Derived.__rmul__。
为了完整起见,*和mul在pandas上下文中有一个不同之处:mul是一个函数,因此可以在变量中传递,并独立使用。例如:
import pandas as pd
pandas_mul = pd.DataFrame.mul
pandas_mul(pd.DataFrame([[1]]), pd.DataFrame([[2]]))另一方面,这将失败:
*(pd.DataFrame([[1]]), pd.DataFrame([[2]]))发布于 2019-04-19 04:23:47
在底层python中,“魔术方法”__mul__和运算符*都是相同的(*只是调用__mul__),正如您所指出的,这就是pythonstadized化处理事物的方式。另一种方法mul是一种可以用于映射(使用map)并避免使用lambda x, y: x*mul的方法。是的,您仍然可以使用__mul__,但是通常这些方法(__x__)并不是用来作为正常函数使用的,一个简单的mul可以使代码更加清晰。
所以,你并不真正“需要”它,但拥有和使用它是很好的。
发布于 2019-04-19 04:26:41
首先,不应该使用第三种方法(df['a'].__mul__(5)),因为它是一个由Python类调用的内部方法。一般来说,用户不接触任何“don”方法。
对于另外两种方法,第一种方法是显而易见的,你只需把它乘以。这是标准数学。
第二种方式变得更有趣。我使用该方法的一个例子是,当要应用的函数是变量时。
例如:
def pandas_math(series, func, val):
return getattr(series, func)(val)pandas_math(df['a'], 'mul', 5)将给出与df['a'].mul(5)相同的结果,但现在您可以将mul作为变量传递,或者传递给您想要使用的任何其他函数。这比硬编码所有的符号容易得多。
https://stackoverflow.com/questions/55756505
复制相似问题