我想创建一个简单的链式管道,我发现this https://stackoverflow.com/questions/33658355/piping-output-from-one-function-to-another-using-python-infix-syntax简单的例子:
"""
From https://stackoverflow.com/questions/33658355/piping-output-from-one-function-to-another-using-python-infix-syntax
"""
import collections
def pipe(original):
"""
"""
class PipeInto(object):
data = {'function': original}
def __init__(self, *args, **kwargs):
self.data['args'] = args
self.data['kwargs'] = kwargs
def __rrshift__(self, other):
return self.data['function'](
other,
*self.data['args'],
**self.data['kwargs']
)
def __call__(self):
return self.data['function'](
*self.data['args'],
**self.data['kwargs']
)
return PipeInto
@pipe
def select(df, *args):
cols = [x for x in args]
return df[cols]
虽然df >> select('one')
工作正常,pipe= select(df, 'one')
返回一个需要调用的对象。怎么能select(df, 'one')
作为一个简单的函数调用,返回过滤后的数据帧?
好吧,我可以想到一个解决方案,但有一个警告:你的原始函数不能采用第二个位置参数,即 pandas 数据帧(关键字参数是可以的)。让我们抛弃__call__
并添加一个__new__
方法到我们的PipeInto
装饰器内部的类。这个新的构造函数测试第一个参数是否是数据帧,如果是,那么我们只需使用参数调用原始函数:
def __new__(cls, *args, **kwargs):
if args and isinstance(args[0], pd.DataFrame):
return cls.data['function'](*args, **kwargs)
return super().__new__(cls)
它似乎有效,如果您发现任何缺点,请告诉我。
>>> df = pd.DataFrame({'one' : [1., 2., 3., 4., 4.],
'two' : [4., 3., 2., 1., 3.]})
>>> select(df, 'one')
one
0 1.0
1 2.0
2 3.0
3 4.0
4 4.0
>>> df >> select('one')
one
0 1.0
1 2.0
2 3.0
3 4.0
4 4.0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)