我试图使用Python/Pandas(作为一个学习练习)大致复制R中的dplyr包。我被困在“管道”功能上。
在R/dplyr中,这是使用管道运算符%>%
完成的,其中x %>% f(y)
相当于f(x, y)
。如果可能的话,我想使用中缀语法复制它(请参见here)。
为了说明这一点,请考虑下面的两个函数。
import pandas as pd
def select(df, *args):
cols = [x for x in args]
df = df[cols]
return df
def rename(df, **kwargs):
for name, value in kwargs.items():
df = df.rename(columns={'%s' % name: '%s' % value})
return df
第一个函数接受一个dataframe并只返回给定的列。第二个获取数据帧,并重命名给定的列。例如:
d = {'one' : [1., 2., 3., 4., 4.],
'two' : [4., 3., 2., 1., 3.]}
df = pd.DataFrame(d)
# Keep only the 'one' column.
df = select(df, 'one')
# Rename the 'one' column to 'new_one'.
df = rename(df, one = 'new_one')
为了使用pipe/infix语法实现相同的功能,代码如下:
df = df | select('one') \
| rename(one = 'new_one')
所以|
左侧的输出作为第一个参数传递给右侧的函数。每当我看到这样的事情完成时(例如,here),它就涉及lambda函数。是否可以用同样的方式在函数之间传递Pandas的数据帧?
我知道Pandas有.pipe
方法,但对我来说重要的是我提供的示例的语法。任何帮助都将不胜感激。
使用逐位
or
运算符很难实现这一点,因为pandas.DataFrame
实现了它。如果您不介意用>>
替换|
,您可以尝试:然后你可以:
在Python 3中,您可以滥用unicode:
[更新]
装修师怎么样?
现在您可以修饰任何将
DataFrame
作为第一个参数的函数:Python真棒!
我知道像Ruby这样的语言“非常有表现力”,它鼓励人们把每一个程序都写成新的DSL,但这在Python中有点不受欢迎。许多pythonist认为为了不同的目的而重载操作符是一种罪恶的亵渎。
[更新]
用户OHLÁLÁ不以为然:
您可以实现dunder调用方法:
然后:
看来要取悦OHLÁLÁ很不容易:
好吧,我可以想出一个解决方案,但有一个警告:您的原始函数不能采用第二个位置参数,即pandas数据帧(关键字参数是可以的)。让我们在docorator中的
__new__
类中添加一个PipeInto
方法,该类测试第一个参数是否是数据帧,如果是,则使用参数调用原始函数:这似乎是可行的,但可能有一些缺点我无法发现。
您可以使用sspipe库,并使用以下语法:
虽然我不得不提到在Python中使用dplyr in Python可能是在dplyr中最接近的事情(它有rshift操作符,但作为一个噱头),但我也要指出,pipe操作符可能只在R中是必需的,因为它使用泛型函数而不是方法作为对象属性。Method chaining为您提供了基本相同的功能,而无需重写运算符:
请注意,在一对圆括号之间包装链可以将其拆分为多行,而无需在每行上拖尾
\
。相关问题 更多 >
编程相关推荐