अजगर में कार्यात्मक पाइप जैसे आर> के मैग्रीट्र्र से%>%


84

आर (धन्यवाद magritrr) में अब आप अधिक कार्यात्मक पाइपिंग सिंटैक्स के साथ संचालन कर सकते हैं %>%। इसका मतलब यह है कि इस कोडिंग के बजाय:

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

आप यह भी कर सकते हैं:

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

मेरे लिए यह अधिक पठनीय है और यह डेटाफ़्रेम से परे मामलों का उपयोग करने के लिए विस्तारित होता है। क्या अजगर भाषा में कुछ इसी तरह का समर्थन है?


1
बड़ा सवाल है। मुझे विशेष रूप से मामले में दिलचस्पी है, जहां कार्यों में अधिक तर्क हैं। के रूप में crime_by_state %>% filter(State=="New York", Year==2005) ...के अंत से कैसे dplyr मेरे सबसे आम आर मुहावरों को बदल दिया
पियोट्र मिगडाल

1
बेशक, कोई इसे बहुत से लंबोदर, नक्शे और कम कर सकता है (और ऐसा करने के लिए यह सीधा है), लेकिन संक्षिप्तता और पठनीयता मुख्य बिंदु हैं।
पायोत्र मिग्डल

12
प्रश्न में पैकेज मैग्रीट है।
पिकोल्बो

1
हां, इसी कारण से हर आर पैकेज को हेडली ने लिखा था। वह अधिक जाना जाता है। (खराब तरीके से प्रच्छन्न ईर्ष्या चेतावनी यहाँ)
piccolbo

1
के जवाब देखें stackoverflow.com/questions/33658355/... कि इस समस्या को हल कर रहे हैं।
पिओटर मिग्डल

जवाबों:


34

ऐसा करने का एक संभावित तरीका एक मॉड्यूल का उपयोग करके है macropy। मैक्रोपी आपको उस कोड में परिवर्तन लागू करने की अनुमति देता है जो आपने लिखा है। इस प्रकार में a | bतब्दील किया जा सकता है b(a)। इसके कई फायदे और नुकसान हैं।

सिल्वेन लेरौक्स द्वारा उल्लिखित समाधान की तुलना में, मुख्य लाभ यह है कि आपको जिन कार्यों का उपयोग करने में रुचि है उनके लिए इन्फिक्स ऑब्जेक्ट बनाने की आवश्यकता नहीं है - बस कोड के क्षेत्रों को चिह्नित करें जिन्हें आप परिवर्तन का उपयोग करने का इरादा रखते हैं। दूसरे, चूंकि परिवर्तन संकलित समय पर लागू होता है, रनटाइम के बजाय, परिवर्तित कोड रनटाइम के दौरान कोई ओवरहेड ग्रस्त है - सभी कार्य तब किए जाते हैं जब बाइट कोड पहली बार स्रोत कोड से उत्पन्न होता है।

मुख्य नुकसान यह है कि मैक्रोपी को काम करने के लिए सक्रिय करने के लिए एक निश्चित तरीके की आवश्यकता होती है (बाद में उल्लेख किया गया है)। एक तेज रनटाइम के विपरीत, स्रोत कोड की पार्सिंग अधिक कम्प्यूटेशनल रूप से जटिल है और इसलिए कार्यक्रम को शुरू होने में अधिक समय लगेगा। अंत में, यह एक वाक्यात्मक शैली जोड़ता है जिसका अर्थ है कि प्रोग्रामर जो मैक्रोपी से परिचित नहीं हैं उन्हें समझने के लिए आपका कोड कठिन हो सकता है।

उदाहरण कोड:

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 कहा है क्योंकि एक प्रक्रिया से दूसरी प्रक्रिया में आउटपुट पास करने के लिए इसका शेल शेल सिंटैक्स है।

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)

2
बहुत अच्छा लगता है, लेकिन जैसा कि मैंने देखा कि यह केवल पायथन 2.7 पर काम करता है (और पायथन 3.4 नहीं)।
पायोटर मिग्डल

3
मैंने बिना किसी निर्भरता वाले एक छोटे से पुस्तकालय का निर्माण किया है, जो @fpipe डेकोरेटर के समान काम करता है, लेकिन (या) के बजाय राइट शिफ्ट (>>) को फिर से परिभाषित कर रहा है: ( pypi.org/project/pipeop
Robin Hilliard

कई सज्जाकारों के उपयोग के साथ तीसरे पक्ष के पुस्तकालयों की आवश्यकता के रूप में डाउनवोट किया गया, यह काफी सरल समस्या के लिए एक बहुत ही जटिल समाधान है। इसके अलावा यह एक अजगर 2 केवल समाधान है। बहुत यकीन है कि वेनिला अजगर समाधान के रूप में अच्छी तरह से जल्दी होने वाला है।
jrmm

37

पंडों 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

NB: पंडों संस्करण पायथन के संदर्भ शब्दार्थ को बरकरार रखता है। इसलिए length_times_widthरिटर्न वैल्यू की जरूरत नहीं है; यह xजगह में संशोधन करता है।


4
दुर्भाग्य से यह केवल डेटाफ्रेम के लिए काम करता है, इसके लिए मैं इसका सही उत्तर नहीं दे सकता। लेकिन यहाँ उल्लेख करने के लिए अच्छा है कि मुख्य उपयोग के मामले में मेरे दिमाग में डेटाफ़्रेम के लिए इसे लागू करना था।
कैंटचूचिस

22

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'

1
PyToolz एक बेहतरीन पॉइंटर है। यह कहते हुए कि एक कड़ी मर चुकी है और दूसरा जल्द ही मर रहा है
akhmed

2
उसका आधार URL लगता है: http://matthewrocklin.com/blog और PyToolz toolz.readthedocs.io/en/latest । आह,
इंटरनेटज की प्रसिद्धि

18

क्या अजगर भाषा में कुछ इसी तरह का समर्थन है?

"अधिक कार्यात्मक पाइपिंग सिंटैक्स" क्या यह वास्तव में अधिक "कार्यात्मक" सिंटैक्स है? मैं कहूंगा कि यह R के बजाय "infix" सिंटैक्स जोड़ता है।

यह कहा जा रहा है, पायथन के व्याकरण में मानक संचालकों से परे infix संकेतन के लिए प्रत्यक्ष समर्थन नहीं है।


यदि आपको वास्तव में ऐसा कुछ चाहिए, तो आपको अपने खुद के infix नोटेशन को लागू करने के लिए शुरुआती बिंदु के रूप में 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

18

यदि आप इसे केवल व्यक्तिगत स्क्रिप्टिंग के लिए चाहते हैं, तो आप पायथन के बजाय नारियल का उपयोग करने पर विचार कर सकते हैं ।

नारियल पायथन का सुपरसेट है। इसलिए आप कोकोनट के पाइप ऑपरेटर का उपयोग कर सकते हैं |>, जबकि पूरी तरह से नारियल भाषा के बाकी हिस्सों को अनदेखा कर सकते हैं।

उदाहरण के लिए:

def addone(x):
    x + 1

3 |> addone

के लिए संकलित करता है

# lots of auto-generated header junk

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

def addone(x):
    return x + 1

(addone)(3)

print(1 |> isinstance(int))... TypeError: isinstance अपेक्षित 2 तर्क, 1
nyanpasu64

1
@ jimbo1qaz यदि आपके पास अभी भी यह समस्या है, तो प्रयास करें print(1 |> isinstance$(int)), या अधिमानतः 1 |> isinstance$(int) |> print
सोलोमन उको

@ सॉलोमन उको आपका जवाब गलत है। पाइथन के धारावाहिकों में $ नक्शे के बाद से 1 |> print$(2)कॉल print(2, 1)। लेकिन मैं चाहता हूं कि print(1, 2)जो UFCS और मैग्रीट से मेल खाता हो। प्रेरणा: 1 |> add(2) |> divide(6)0.5 होनी चाहिए, और मुझे कोष्ठक की आवश्यकता नहीं होनी चाहिए।
nyanpasu64

@ jimbo1qaz हाँ, ऐसा लगता है कि मेरी पिछली टिप्पणी गलत है। आपको वास्तव में आवश्यकता होगी 1 |> isinstance$(?, int) |> print। अपने अन्य उदाहरण के लिए: 1 |> print$(?, 2), 1 |> (+)$(?, 2) |> (/)$(?, 6)। मुझे नहीं लगता कि आप आंशिक आवेदन के लिए कोष्ठक से बच सकते हैं।
सोलोमन उकॉ

पर कैसे बदसूरत दोनों की तलाश में |>और (+)$(?, 2)है, मैं निष्कर्ष है कि प्रोग्रामिंग भाषा और गणित स्थापना मुझे वाक्य रचना के इस प्रकार का उपयोग नहीं करना चाहता है पर आए हैं, और कोष्ठक का एक सेट का सहारा से भी भद्दा बनाता है। अगर इसका बेहतर सिंटैक्स होता तो मैं इसका इस्तेमाल करता। (उदाहरण के लिए। Dlang में UFCS है लेकिन अंकगणितीय कार्यों के बारे में IDK है, या यदि पायथन में ..पाइप ऑपरेटर है)।
nyanpasu64

11

नहीं है dfplyमॉड्यूल। आप पर अधिक जानकारी पा सकते हैं

https://github.com/kieferk/dfply

कुछ उदाहरण निम्न हैं:

from dfply import *
diamonds >> group_by('cut') >> row_slice(5)
diamonds >> distinct(X.color)
diamonds >> filter_by(X.cut == 'Ideal', X.color == 'E', X.table < 55, X.price < 500)
diamonds >> mutate(x_plus_y=X.x + X.y, y_div_z=(X.y / X.z)) >> select(columns_from('x')) >> head(3)

इसे मेरी राय में, सही उत्तर के रूप में चिह्नित किया जाना चाहिए। इसके अलावा, यह प्रतीत होता है कि दोनों dfplyऔर dplythonएक ही संकुल रहे हैं। क्या उनके बीच कोई अंतर है? @BigDataScientist
InfiniteFlash

dfply, dplython, plydataसंकुल की अजगर बंदरगाह हैं dplyrपैकेज ताकि वे सुंदर वाक्य रचना में इसी तरह के होने जा रहे हैं।
BigDataScientist

9

मैं एलिक्सिर से |>पाइप ऑपरेटर को चूक गया, इसलिए मैंने एक साधारण फंक्शन डेकोरेटर (~ कोड की 50 पंक्तियाँ) बनाईं, जो >>पायथन राइट शिफ्ट ऑपरेटर को एक बहुत ही एलिशिर-जैसे पाइप के रूप में पुन: स्थापित करता है, जो अस्ति पुस्तकालय और संकलन या निष्पादन का उपयोग करते हुए किया जाता है:

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


9

आप sspipe पुस्तकालय का उपयोग कर सकते हैं । यह दो वस्तुओं को उजागर करता है pऔर px। इसके समान 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

के pipeसाथ भवनInfix

जैसा कि सिल्वेन लेरॉक्स द्वारा संकेत दिया गया है , हम Infixऑपरेटर का उपयोग एक इन्फिक्स बनाने में कर सकते हैं pipe। आइए देखें कि यह कैसे पूरा होता है।

सबसे पहले, यहाँ तोमर फिलिबा का कोड है

कोड नमूना और टिप्पणियाँ 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)

अजगर में कुछ इसी तरह हासिल करने का सबसे आसान तरीका है करी का उपयोग करनाtoolzपुस्तकालय एक प्रदान करता है curryडेकोरेटर समारोह आसान curried कार्यों का निर्माण कर देता है।

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)

करी कार्यों को डिजाइन करते समय, स्थिर तर्क (यानी कई उदाहरणों के लिए उपयोग किए जाने वाले तर्क) को पहले पैरामीटर सूची में रखा जाना चाहिए।

ध्यान दें कि मॉड्यूल 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

अन्य infix सीमांकक का उपयोग करना

आप अन्य Python ऑपरेटर विधियों को ओवरराइड करके Infix इनवोकेशन को घेरने वाले प्रतीकों को बदल सकते हैं। उदाहरण के लिए, स्विचिंग __or__और __ror__करने के लिए __mod__और __rmod__बदल जाएगा |करने के लिए ऑपरेटर modऑपरेटर।

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

6

मेरा 2 सी जोड़ना। मैं व्यक्तिगत रूप से कार्यात्मक शैली प्रोग्रामिंग के लिए पैकेज fn का उपयोग करता हूं । आपका उदाहरण में अनुवाद करता है

from fn import F, _
from math import sqrt

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

Fआंशिक अनुप्रयोग और संरचना के लिए कार्यात्मक-शैली वाली चीनी के साथ एक आवरण वर्ग है। _अनाम कार्यों (पायथन के समान lambda) के लिए एक स्काला शैली निर्माता है ; यह एक चर का प्रतिनिधित्व करता है, इसलिए आप _अधिक तर्कों के साथ एक फ़ंक्शन प्राप्त करने के लिए एक अभिव्यक्ति में कई वस्तुओं को जोड़ सकते हैं (जैसे _ + _कि बराबर है lambda a, b: a + b)। F(sqrt) >> _**2 >> strएक Callableवस्तु में परिणाम जो आप चाहते हैं के रूप में कई बार इस्तेमाल किया जा सकता है।


बस मैं क्या देख रहा हूँ - यहां तक ​​कि एक चित्रण के रूप में भी स्केला का उल्लेख किया। इसे अभी
आज़मा

@javadba मुझे खुशी है कि आपने इसे उपयोगी पाया है। ध्यान दें, _यह 100% लचीला नहीं है: यह सभी पायथन ऑपरेटरों का समर्थन नहीं करता है। अतिरिक्त, यदि आप _एक इंटरैक्टिव सत्र में उपयोग करने की योजना बनाते हैं, तो आपको इसे किसी अन्य नाम (जैसे from fn import _ as var) के तहत आयात करना चाहिए , क्योंकि अधिकांश (यदि सभी नहीं) इंटरैक्टिव पाइथन गोले _अंतिम अप्रकाशित मान का प्रतिनिधित्व करने के लिए उपयोग करते हैं, इस प्रकार आयातित वस्तु को छायांकित करते हैं।
एली कोरविगो

5

पाइप फ़ंक्शन को लागू करने के लिए 3 पार्टी पुस्तकालयों या भ्रमित करने वाली ऑपरेटर प्रवंचना की कोई आवश्यकता नहीं है - आप मूल रूप से अपने आप को आसानी से जा सकते हैं।

एक पाइप फ़ंक्शन वास्तव में क्या है, इसे परिभाषित करके शुरू करते हैं। इसके दिल में, यह तार्किक क्रम में फ़ंक्शन कॉल की एक श्रृंखला को व्यक्त करने का एक तरीका है, बजाय मानक 'इनसाइड आउट' क्रम के।

उदाहरण के लिए, इन कार्यों को देखने देता है:

def one(value):
  return value

def two(value):
  return 2*value

def three(value):
  return 3*value

बहुत दिलचस्प नहीं है, लेकिन मान लें कि दिलचस्प चीजें हो रही हैं value। हम उन्हें क्रम में कॉल करना चाहते हैं, प्रत्येक के आउटपुट को अगले में पास करना। वेनिला अजगर में जो होगा:

result = three(two(one(1)))

यह अविश्वसनीय रूप से पठनीय नहीं है और अधिक जटिल पाइपलाइनों के लिए इसका बुरा होने वाला है। तो, यहाँ एक सरल पाइप फ़ंक्शन है जो एक प्रारंभिक तर्क लेता है, और इसे लागू करने के लिए कार्यों की श्रृंखला:

def pipe(first, *args):
  for fn in args:
    first = fn(first)
  return first

चलो इसे कहते हैं:

result = pipe(1, one, two, three)

यह मेरे लिए बहुत पठनीय 'पाइप' वाक्य रचना जैसा दिखता है :)। मैं यह नहीं देखता कि यह ओवरलोडिंग ऑपरेटरों या उस जैसी किसी भी चीज़ से कम पठनीय कैसे है। वास्तव में, मैं तर्क दूंगा कि यह अधिक पठनीय अजगर कोड है

यहाँ ओपी के उदाहरणों को हल करने वाला विनम्र पाइप है:

from math import sqrt
from datetime import datetime

def as_date(s):
  return datetime.strptime(s, '%Y-%m-%d')

def as_character(value):
  # Do whatever as.character does
  return value

pipe("2014-01-01", as_date)
pipe(12, sqrt, lambda x: x**2, as_character)

3

एक वैकल्पिक समाधान वर्कफ़्लो टूल dask का उपयोग करना होगा। हालांकि यह उतना मज़ेदार नहीं है जितना ...

var
| do this
| then do that

... यह अभी भी आपके चर को श्रृंखला के नीचे प्रवाहित करने की अनुमति देता है और डस्क का उपयोग करके समानांतरकरण का जोड़ा लाभ देता है जहां संभव हो।

यहां बताया गया है कि मैं पाइप-चेन पैटर्न को पूरा करने के लिए dask का उपयोग कैसे करता हूं:

import dask

def a(foo):
    return foo + 1
def b(foo):
    return foo / 2
def c(foo,bar):
    return foo + bar

# pattern = 'name_of_behavior': (method_to_call, variables_to_pass_in, variables_can_be_task_names)
workflow = {'a_task':(a,1),
            'b_task':(b,'a_task',),
            'c_task':(c,99,'b_task'),}

#dask.visualize(workflow) #visualization available. 

dask.get(workflow,'c_task')

# returns 100

अमृत ​​के साथ काम करने के बाद मैं पायथन में पाइपिंग पैटर्न का उपयोग करना चाहता था। यह बिल्कुल वैसा ही पैटर्न नहीं है, लेकिन यह समान है और जैसा मैंने कहा, समानांतरकरण के अतिरिक्त लाभ के साथ आता है; यदि आप अपने वर्कफ़्लो में एक कार्य प्राप्त करने के लिए कहते हैं जो दूसरों को पहले चलाने के लिए निर्भर नहीं है, तो वे समानांतर में चलेंगे।

यदि आप आसान वाक्यविन्यास चाहते थे तो आप इसे किसी ऐसी चीज में लपेट सकते हैं जो आपके लिए कार्यों के नामकरण का ध्यान रखे। बेशक इस स्थिति में आपको पहले तर्क के रूप में पाइप को लेने के लिए सभी कार्यों की आवश्यकता होगी, और आप लंबन के किसी भी लाभ को खो देंगे। लेकिन अगर आप इसके साथ ठीक हैं तो आप ऐसा कुछ कर सकते हैं:

def dask_pipe(initial_var, functions_args):
    '''
    call the dask_pipe with an init_var, and a list of functions
    workflow, last_task = dask_pipe(initial_var, {function_1:[], function_2:[arg1, arg2]})
    workflow, last_task = dask_pipe(initial_var, [function_1, function_2])
    dask.get(workflow, last_task)
    '''
    workflow = {}
    if isinstance(functions_args, list):
        for ix, function in enumerate(functions_args):
            if ix == 0:
                workflow['task_' + str(ix)] = (function, initial_var)
            else:
                workflow['task_' + str(ix)] = (function, 'task_' + str(ix - 1))
        return workflow, 'task_' + str(ix)
    elif isinstance(functions_args, dict):
        for ix, (function, args) in enumerate(functions_args.items()):
            if ix == 0:
                workflow['task_' + str(ix)] = (function, initial_var)
            else:
                workflow['task_' + str(ix)] = (function, 'task_' + str(ix - 1), *args )
        return workflow, 'task_' + str(ix)

# piped functions
def foo(df):
    return df[['a','b']]
def bar(df, s1, s2):
    return df.columns.tolist() + [s1, s2]
def baz(df):
    return df.columns.tolist()

# setup 
import dask
import pandas as pd
df = pd.DataFrame({'a':[1,2,3],'b':[1,2,3],'c':[1,2,3]})

अब, इस आवरण के साथ, आप इनमें से किसी भी सिन्थेटिक पैटर्न के बाद एक पाइप बना सकते हैं:

# wf, lt = dask_pipe(initial_var, [function_1, function_2])
# wf, lt = dask_pipe(initial_var, {function_1:[], function_2:[arg1, arg2]})

इस तरह:

# test 1 - lists for functions only:
workflow, last_task =  dask_pipe(df, [foo, baz])
print(dask.get(workflow, last_task)) # returns ['a','b']

# test 2 - dictionary for args:
workflow, last_task = dask_pipe(df, {foo:[], bar:['string1', 'string2']})
print(dask.get(workflow, last_task)) # returns ['a','b','string1','string2']

इसके साथ एक समस्या यह है कि आप कार्यों को तर्क के रूप में पारित नहीं कर सकते हैं :(
लेगिट स्टैक

2

यहाँ बहुत अच्छा pipeमॉड्यूल है https://pypi.org/project/pipe/ यह ओवरलोड | ऑपरेटर और बहुत सारे पाइप-फ़ंक्शन प्रदान करते हैं जैसे कि add, first, where, tailआदि।

>>> [1, 2, 3, 4] | where(lambda x: x % 2 == 0) | add
6

>>> sum([1, [2, 3], 4] | traverse)
10

साथ ही खुद के पाइप-फंक्शन लिखना बहुत आसान है

@Pipe
def p_sqrt(x):
    return sqrt(x)

@Pipe
def p_pr(x):
    print(x)

9 | p_sqrt | p_pr

0

पांडा के साथ पंडों के तरीकों की रचना करके पाइप की कार्यक्षमता को प्राप्त किया जा सकता है। नीचे एक उदाहरण दिया गया है।

एक नमूना डेटा फ़्रेम लोड करें:

import seaborn    
iris = seaborn.load_dataset("iris")
type(iris)
# <class 'pandas.core.frame.DataFrame'>

बिंदु के साथ पंडों के तरीकों की संरचना का चित्रण करें:

(iris.query("species == 'setosa'")
     .sort_values("petal_width")
     .head())

यदि आवश्यक हो तो आप पांडा डेटा फ्रेम में नए तरीके जोड़ सकते हैं ( उदाहरण के लिए यहां किया गया है ):

pandas.DataFrame.new_method  = new_method
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.