热门标签 | 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对象可以根据需要多次使用.


推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
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社区 版权所有