热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python中的功能管道,如R'sdplyr中的%>%

如何解决《python中的功能管道,如R'sdplyr中的%>%》经验,为你挑选了9个好方法。

在R(感谢magritrr)中,您现在可以通过更多功能管道语法执行操作%>%.这意味着不是编码:

> as.Date("2014-01-01")
> as.character((sqrt(12)^2)

你也可以这样做:

> "2014-01-01" %>% as.Date 
> 12 %>% sqrt %>% .^2 %>% as.character

对我来说,这更具可读性,这扩展到数据框之外的用例.python语言是否支持类似的东西?



1> Dunes..:

一种可能的方法是使用一个名为的模块macropy.Macropy允许您将转换应用于您编写的代码.因此a | b可以转化为b(a).这具有许多优点和缺点.

与Sylvain Leroux提到的解决方案相比,主要优点是您不需要为您感兴趣的函数创建中缀对象 - 只需标记您打算使用转换的代码区域.其次,由于转换是在编译时而不是运行时应用的,因此转换后的代码在运行时不会产生任何开销 - 所有工作都是在首次从源代码生成字节代码时完成的.

主要的缺点是,macropy需要激活某种方式才能使其工作(稍后提到).与更快的运行时相比,源代码的解析在计算上更复杂,因此程序将花费更长的时间来启动.最后,它添加了一种语法风格,这意味着不熟悉macropy的程序员可能会发现您的代码难以理解.

示例代码:

run.py

import macropy.activate 
# Activates macropy, modules using macropy cannot be imported before this statement
# in the program.
import target
# import the module using macropy

target.py

from fpipe import macros, fpipe
from macropy.quick_lambda import macros, f
# The `from module import macros, ...` must be used for macropy to know which 
# macros it should apply to your code.
# Here two macros have been imported `fpipe`, which does what you want
# and `f` which provides a quicker way to write lambdas.

from math import sqrt

# Using the fpipe macro in a single expression.
# The code between the square braces is interpreted as - str(sqrt(12))
print fpipe[12 | sqrt | str] # prints 3.46410161514

# using a decorator
# All code within the function is examined for `x | y` constructs.
x = 1 # global variable
@fpipe
def sum_range_then_square():
    "expected value (1 + 2 + 3)**2 -> 36"
    y = 4 # local variable
    return range(x, y) | sum | f[_**2]
    # `f[_**2]` is macropy syntax for -- `lambda x: x**2`, which would also work here

print sum_range_then_square() # prints 36

# using a with block.
# same as a decorator, but for limited blocks.
with fpipe:
    print range(4) | sum # prints 6
    print 'a b c' | f[_.split()] # prints ['a', 'b', 'c']

最后是努力工作的模块.我将其称为fpipe for function pipe作为其模拟shell语法,用于将输出从一个进程传递到另一个进程.

fpipe.py

from macropy.core.macros import *
from macropy.core.quotes import macros, q, ast

macros = Macros()

@macros.decorator
@macros.block
@macros.expr
def fpipe(tree, **kw):

    @Walker
    def pipe_search(tree, stop, **kw):
        """Search code for bitwise or operators and transform `a | b` to `b(a)`."""
        if isinstance(tree, BinOp) and isinstance(tree.op, BitOr):
            operand = tree.left
            function = tree.right
            newtree = q[ast[function](ast[operand])]
            return newtree

    return pipe_search.recurse(tree)


听起来不错,但我认为它只适用于Python 2.7(而不是Python 3.4).
我创建了一个没有依赖项的较小的库,该库的作用与@fpipe装饰器相同,但重新定义了右移(>>)而不是or(|):https://pypi.org/project/pipeop/

2> shadowtalker..:

管道是Pandas 0.16.2中的新功能.

例:

import pandas as pd
from sklearn.datasets import load_iris

x = load_iris()
x = pd.DataFrame(x.data, columns=x.feature_names)

def remove_units(df):
    df.columns = pd.Index(map(lambda x: x.replace(" (cm)", ""), df.columns))
    return df

def length_times_width(df):
    df['sepal length*width'] = df['sepal length'] * df['sepal width']
    df['petal length*width'] = df['petal length'] * df['petal width']

x.pipe(remove_units).pipe(length_times_width)
x

注意:Pandas版本保留了Python的引用语义.这就是为什么length_times_width不需要返回值; 它修改x到位.


遗憾的是,这仅适用于数据帧,因此我无法将其指定为正确的答案.但很高兴在这里提到我想到的主要用例是将其应用于数据帧.

3> Sylvain Lero..:

python语言是否支持类似的东西?

"更多功能管道语法"这真的是一个更"功能"的语法吗?我会说它为R添加了一个"中缀"语法.

话虽这么说,Python的语法并没有直接支持标准运算符之外的中缀表示法.


如果你真的需要这样的东西,你应该从Tomer Filiba那里获取代码作为实现你自己的中缀表示法的起点:

代码示例和评论由Tomer Filiba(http://tomerfiliba.com/blog/Infix-Operators/):

from functools import partial

class Infix(object):
    def __init__(self, func):
        self.func = func
    def __or__(self, other):
        return self.func(other)
    def __ror__(self, other):
        return Infix(partial(self.func, other))
    def __call__(self, v1, v2):
        return self.func(v1, v2)

使用这个特殊类的实例,我们现在可以使用一个新的"语法"来调用函数作为中缀运算符:

>>> @Infix
... def add(x, y):
...     return x + y
...
>>> 5 |add| 6



4> smci..:

PyToolz [doc]允许任意组合管道,只是它们没有用管道操作符语法定义.

请按照上面的链接进行快速入门.这是一个视频教程:http: //pyvideo.org/video/2858/functional-programming-in-python-with-pytoolz

In [1]: from toolz import pipe

In [2]: from math import sqrt

In [3]: pipe(12, sqrt, str)
Out[3]: '3.4641016151377544'



5> shadowtalker..:

如果您只想将其用于个人脚本,您可能需要考虑使用Coconut而不是Python.

椰子是Python的超集.因此,您可以使用Coconut的管道操作员|>,同时完全忽略椰子语言的其余部分.

例如:

def addone(x):
    x + 1

3 |> addone

编译成

# lots of auto-generated header junk

# Compiled Coconut: -----------------------------------------------------------

def addone(x):
    return x + 1

(addone)(3)



6> Robin Hillia..:

我错过了|>Elixir 的管道操作符,所以我创建了一个简单的函数装饰器(大约50行代码),>>在编译时使用ast库和compile/exec 将Python右移操作符重新解释为类似Elixir的管道:

from pipeop import pipes

def add3(a, b, c):
    return a + b + c

def times(a, b):
    return a * b

@pipes
def calc()
    print 1 >> add3(2, 3) >> times(4)  # prints 24

它所做的只是重写a >> b(...)b(a, ...).

https://pypi.org/project/pipeop/

https://github.com/robinhilliard/pipes



7> mhsekhavat..:

您可以使用sspipe库。它暴露了两个对象ppx。类似于x %>% f(y,z),您可以写作,x | p(f, y, z)并且类似于x %>% .^2您可以写作x | px**2

from sspipe import p, px
from math import sqrt

12 | p(sqrt) | px ** 2 | p(str)



8> yardsale8..:

建筑pipeInfix

正如Sylvain Leroux所暗示,我们可以使用Infix运算符来构造中缀pipe.让我们看看这是如何实现的.

首先,这是Tomer Filiba的代码

代码示例和评论由Tomer Filiba(http://tomerfiliba.com/blog/Infix-Operators/):

from functools import partial

class Infix(object):
    def __init__(self, func):
        self.func = func
    def __or__(self, other):
        return self.func(other)
    def __ror__(self, other):
        return Infix(partial(self.func, other))
    def __call__(self, v1, v2):
        return self.func(v1, v2)

使用这个特殊类的实例,我们现在可以使用一个新的"语法"来调用函数作为中缀运算符:

>>> @Infix
... def add(x, y):
...     return x + y
...
>>> 5 |add| 6

管道运算符将前一个对象作为参数传递给管道后面的对象,因此x %>% f可以转换为f(x).因此,pipe可以使用Infix如下定义运算符:

In [1]: @Infix
   ...: def pipe(x, f):
   ...:     return f(x)
   ...:
   ...:

In [2]: from math import sqrt

In [3]: 12 |pipe| sqrt |pipe| str
Out[3]: '3.4641016151377544'

关于部分申请的说明

%>%从运营商dpylr通过在函数的第一个参数推参数,所以

df %>% 
filter(x >= 2) %>%
mutate(y = 2*x)

对应于

df1 <- filter(df, x >= 2)
df2 <- mutate(df1, y = 2*x)

在Python中实现类似功能的最简单方法是使用currying.该toolz库提供了一个curry装饰器功能,可以轻松构建curry函数.

In [2]: from toolz import curry

In [3]: from datetime import datetime

In [4]: @curry
    def asDate(format, date_string):
        return datetime.strptime(date_string, format)
    ...:
    ...:

In [5]: "2014-01-01" |pipe| asDate("%Y-%m-%d")
Out[5]: datetime.datetime(2014, 1, 1, 0, 0)

请注意,|pipe|将参数推送到最后一个参数位置,即

x |pipe| f(2)

对应于

f(2, x)

在设计curried函数时,应该在参数列表的前面放置静态参数(即可能用于许多示例的参数).

请注意,toolz其中包括许多预先计算的功能,包括operator模块中的各种功能.

In [11]: from toolz.curried import map

In [12]: from toolz.curried.operator import add

In [13]: range(5) |pipe| map(add(2)) |pipe| list
Out[13]: [2, 3, 4, 5, 6]

其大致对应于R中的以下内容

> library(dplyr)
> add2 <- function(x) {x + 2}
> 0:4 %>% sapply(add2)
[1] 2 3 4 5 6

使用其他中缀分隔符

您可以通过覆盖其他Python运算符方法来更改围绕Infix调用的符号.例如,交换__or____ror____mod____rmod__将改变|操作者的mod操作者.

In [5]: 12 %pipe% sqrt %pipe% str
Out[5]: '3.4641016151377544'



9> Eli Korvigo..:

添加我的2c.我个人使用package fn进行功能样式编程.你的例子转化为

from fn import F, _
from math import sqrt

(F(sqrt) >> _**2 >> str)(12)

F是一个包装类,具有功能风格的语法糖,用于部分应用和组合._是一个用于匿名函数的Scala样式构造函数(类似于Python lambda); 它表示一个变量,因此您可以_在一个表达式中组合多个对象以获得具有更多参数的函数(例如_ + _,相当于lambda a, b: a + b).F(sqrt) >> _**2 >> str导致一个Callable对象可以根据需要多次使用.


推荐阅读
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
author-avatar
广药中山校区艺术团啦啦队
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有