আরটির ম্যাজিট্রেট থেকে%>% এর মতো অজগরের কার্যকরী পাইপগুলি


87

আর-তে ( ম্যাজিস্ট্রিটকে ধন্যবাদ ) আপনি এখন আরও কার্যকরী পাইপিং সিনট্যাক্সের মাধ্যমে অপারেশন সম্পাদন করতে পারেন %>%। এর অর্থ এই কোডিংয়ের পরিবর্তে:

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

আপনি এটি করতে পারেন:

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

আমার কাছে এটি আরও পঠনযোগ্য এবং এটি ডেটাফ্রেমের বাইরেও কেসগুলি ব্যবহার করতে প্রসারিত। অজগর ভাষা কি অনুরূপ কিছু জন্য সমর্থন আছে?


4
দুর্দান্ত প্রশ্ন। আমি বিশেষত ক্ষেত্রে আগ্রহী, যেখানে ফাংশনগুলিতে আরও যুক্তি রয়েছে। মতই crime_by_state %>% filter(State=="New York", Year==2005) ...শেষ প্রান্ত থেকে কিভাবে dplyr আমার সবচেয়ে সাধারণ আর বাগধারার প্রতিস্থাপিত
পাইটর মিগডাল

4
অবশ্যই, কেউ এটি প্রচুর ল্যাম্বডাস, মানচিত্র এবং হ্রাস দ্বারা করতে পারে (এবং এটি করা সহজসাধ্য) তবে ব্রেভিটি এবং পঠনযোগ্যতা মূল বিষয়গুলি।
পাইটর মিগডাল

13
প্যাকেজটি প্রশ্নবিদ্ধ mag
পিক্কলবো

4
হ্যাঁ, একই কারণে প্রতি লিখিত প্রতিটি আর প্যাকেজ হ্যাডলি লিখেছিলেন। তিনি বেশি পরিচিত। (এখানে দুর্বল ছদ্মবেশী alert
র্ষা

4
এই সমস্যার সমাধান করছে এমন স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 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

টার্গেট.পি

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.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)

4
দুর্দান্ত শোনায় তবে আমি দেখতে পাচ্ছি এটি কেবল পাইথন ২.7 এ কাজ করে (এবং পাইথন ৩.৪ নয়)।
পাইটর মিগডাল

4
আমি একটি ছোট লাইব্রেরি তৈরি করেছি যাতে কোনও নির্ভরতা নেই যা @ ফাইপ ডেকরেটারের মতো একই কাজ করে তবে ডান শিফট (>>) এর পরিবর্তে বা (|): পিপাই.আর.জি.
রবিন হিলিয়ার্ড

একাধিক অলঙ্করণকারী ব্যবহারের সাথে তৃতীয় পক্ষের গ্রন্থাগারগুলির প্রয়োজনীয়তা হিসাবে ডাউনওয়েট করা মোটামুটি সহজ সমস্যার জন্য খুব জটিল সমাধান। প্লাস এটি অজগর 2 একমাত্র সমাধান। খুব নিশ্চিত যে ভ্যানিলা পাইথন দ্রবণটি দ্রুততর হতে চলেছে।
jramm

40

পাইপগুলি পান্ডাস 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

এনবি: পান্ডাস সংস্করণ পাইথনের রেফারেন্স শব্দার্থকে ধরে রেখেছে। এজন্য length_times_widthকোনও ফেরতের মূল্য প্রয়োজন হয় না; এটি xজায়গায় পরিবর্তিত হয়।


4
দুর্ভাগ্যক্রমে এটি কেবল ডেটাফ্রেমের জন্যই কাজ করে, এজন্য আমি এটিকে সঠিক উত্তর হিসাবে নির্ধারণ করতে পারি না। তবে এখানে আমার প্রধান ব্যবহারের বিষয়টি উল্লেখ করা ভাল, এটি ডেটাফ্রেমে প্রয়োগ করা ছিল।
cantdutchthis এই

22

পাইটুল্জ [ডক] ইচ্ছামত মিশ্রনযোগ্য পাইপগুলিকে অনুমতি দেয়, কেবল সেগুলি পাইপ-অপারেটর সিনট্যাক্স দিয়ে সংজ্ঞায়িত হয় না।

কুইকস্টার্টটির জন্য উপরের লিঙ্কটি অনুসরণ করুন। এবং এখানে একটি ভিডিও টিউটোরিয়াল: 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'

4
পাইটুলজ একটি দুর্দান্ত পয়েন্টার। এক লিঙ্কটি মারা গেছে এবং অন্যটি শীঘ্রই মারা যাচ্ছে
অখমেদ

4
তার বেস ইউআরএলগুলি মনে হচ্ছে: http://matthewrocklin.com/blog এবং পাইটুলজ সরঞ্জামজ.ড্রেডহেডোকস.আইও / এএন / স্ট্লেস্ট । আহ, ইন্টারনেটজগতের ক্ষণস্থায়ীতা ...
স্মি

18

অজগর ভাষা কি অনুরূপ কিছু জন্য সমর্থন আছে?

"আরও কার্যকরী পাইপিং সিনট্যাক্স" এটি কি আরও বেশি "কার্যকরী" সিনট্যাক্স? আমি বলব এটি পরিবর্তে আর এর সাথে একটি "ইনফিক্স" সিনট্যাক্স যুক্ত করে।

বলা হচ্ছে, পাইথনের ব্যাকরণের মান অপারেটরদের বাইরে ইনফিক্স স্বরলিপি দেওয়ার জন্য সরাসরি সমর্থন নেই।


আপনার যদি সত্যিই এর মতো কিছু প্রয়োজন হয় তবে আপনার নিজের ইনফিক্স স্বরলিপিটি প্রয়োগ করতে আপনার কোডটি টোমর ফিলিবা থেকে একটি প্রাথমিক পয়েন্ট হিসাবে নেওয়া উচিত :

কোড নমুনা এবং টোমর ফিলিবা দ্বারা মন্তব্যসমূহ ( 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
nanpasu64

4
@ jimbo1qaz আপনার যদি এখনও সমস্যা থাকে তবে চেষ্টা করুন print(1 |> isinstance$(int))বা বেশি পছন্দ করুন 1 |> isinstance$(int) |> print,।
সলোমন উকো

@ সলোমন উকো আপনার উত্তরটি ভুল। পাই থেকে 1 |> print$(2)calls print(2, 1)পাইথন পার্টিয়ালগুলিতে মানচিত্র। তবে আমি চাই print(1, 2)যা ইউএফসিএস এবং ম্যাজিট্রির সাথে মেলে। অনুপ্রেরণা: 1 |> add(2) |> divide(6)0.5 হওয়া উচিত এবং আমার প্রথম বন্ধনী থাকা উচিত নয়।
nanpasu64

@ জিম্বো 1 কাজ, হ্যাঁ, আমার আগের মন্তব্যটি ভুল বলে মনে হচ্ছে। আপনার আসলে প্রয়োজন হবে 1 |> isinstance$(?, int) |> print। আপনার অন্যান্য উদাহরণের জন্য: 1 |> print$(?, 2), 1 |> (+)$(?, 2) |> (/)$(?, 6)। আমি মনে করি না আপনি আংশিক প্রয়োগের জন্য বন্ধনী এড়াতে পারবেন।
সলোমন উকো

উভয়ই কুরুচিপূর্ণ |>এবং কীভাবে (+)$(?, 2)তা দেখে, আমি এই সিদ্ধান্তে পৌঁছেছি যে প্রোগ্রামিং-ভাষা এবং গণিত সংস্থা আমাকে এই ধরণের সিনট্যাক্স ব্যবহার করতে চায় না, এবং এটি প্রথম বন্ধনীর সংকলনের চেয়ে আরও খারাপ করে তোলে। আমি এটি ব্যবহার করব যদি এটির আরও ভাল বাক্য গঠন থাকে (উদাহরণস্বরূপ: ডালংয়ের গাণিতিক ফাংশন সম্পর্কে ইউএফসিএস থাকে তবে আইডিকে থাকে, বা পাইথনের যদি ..পাইপ অপারেটর থাকে)।
nanpasu64

12

নেই 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একই প্যাকেজ আছে। তাদের মধ্যে কি কোনও পার্থক্য আছে? @ বিগডাটা বিজ্ঞানী
ইনফিনিটিফ্ল্যাশ

dfply, dplython, plydataপ্যাকেজ পাইথন পোর্ট হয় dplyrপ্যাকেজ তাই তারা চমত্কার সিনট্যাক্স অনুরূপ হতে যাচ্ছে।
বিগডেটা সায়েন্টিস্ট

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

সকল তা করছেন rewriting হয় a >> b(...)যেমন b(a, ...)

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

https://github.com/robinhilliard/pype


9

আপনি এসস্পাইপ লাইব্রেরি ব্যবহার করতে পারেন । এটি দুটি বস্তু প্রকাশ করে 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। আসুন দেখুন এটি কীভাবে সম্পন্ন হয়।

প্রথমত, এখানে টমোর ফিলিবা থেকে কোড

কোড নমুনা এবং টোমর ফিলিবা দ্বারা মন্তব্যসমূহ ( 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একটি ফাংশন প্রথম যুক্তি মাধ্যমে push কর্মের আর্গুমেন্ট, তাই

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থেকে বিভিন্ন ফাংশন সহ অনেক প্রাক curried ফাংশন, অন্তর্ভুক্ত 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]

যা মোটামুটি আর এর সাথে নিম্নলিখিতের সাথে মিলে যায়

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

অন্যান্য ইনফিক্স ডিলিমিটার ব্যবহার করে

অন্যান্য পাইথন অপারেটর পদ্ধতিগুলিকে ওভাররাইড করে আপনি ইনফিক্সের অনুরোধকে ঘিরে থাকা প্রতীকগুলি পরিবর্তন করতে পারেন। উদাহরণস্বরূপ, সুইচিং __or__এবং __ror__করতে __mod__এবং __rmod__পরিবর্তন করতে হবে |অপারেটর modঅপারেটর।

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

7

পাইপ ফাংশন বাস্তবায়নের জন্য তৃতীয় পক্ষের লাইব্রেরি বা বিভ্রান্তিকর অপারেটরের কৌশল দরকার নেই - আপনি নিজেরাই বেসিকগুলি খুব সহজেই যেতে পারেন।

পাইপ ফাংশন আসলে কী তা নির্ধারণ করে শুরু করা যাক। এর অন্তরে, এটি কেবলমাত্র 'ইন আউট আউট' ক্রমটির চেয়ে লজিকাল ক্রমে ক্রিয়াকলাপের ধারাবাহিকতা প্রকাশ করার একটি উপায়।

উদাহরণস্বরূপ, আসুন এই ফাংশনগুলি দেখুন:

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)

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বস্তুর ফলাফল ।


শুধু আমি যা খুঁজছি - এমনকি উদাহরণ হিসাবে স্কেল উল্লেখ করেছেন। এখনই চেষ্টা করে
দেখছেন

@ জাভাদ্ব্বা আমি খুশি যে আপনি এই দরকারীটি পেয়েছেন। লক্ষ করুন, এটি _100% নমনীয় নয়: এটি সমস্ত পাইথন অপারেটরকে সমর্থন করে না। সংযোজন, যদি আপনি _একটি ইন্টারেক্টিভ সেশনে ব্যবহার করার পরিকল্পনা করেন তবে আপনার এটি অন্য নামের (যেমন from fn import _ as var) অধীনে আমদানি করা উচিত , কারণ বেশিরভাগ (সমস্ত না থাকলে) ইন্টারেক্টিভ পাইথন শেলগুলি _সর্বশেষ স্বাক্ষরিত প্রত্যাবর্তিত মান উপস্থাপন করতে ব্যবহার করে, এইভাবে আমদানিকৃত বস্তুর ছায়া গোছায়।
এলি করভিগো

3

একটি বিকল্প সমাধান হ'ল ওয়ার্কফ্লো সরঞ্জাম ড্যাস্ক ব্যবহার করা। যদিও এটি সিন্টেক্সিকভাবে মজাদার নয় ...

var
| do this
| then do that

... এটি এখনও আপনার পরিবর্তনশীলটিকে শৃঙ্খলে নেমে যেতে অনুমতি দেয় এবং ড্যাস্ক ব্যবহার করে যেখানে সম্ভব সেখানে সমান্তরালনের অতিরিক্ত সুবিধা দেয়।

পাইপ-চেইন প্যাটার্নটি সম্পাদন করতে আমি কীভাবে ড্যাস্ক ব্যবহার করি তা এখানে:

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']

এর সাথে একটি সমস্যা হ'ল আপনি যুক্তি হিসাবে ফাংশনগুলি পাস করতে পারবেন না :(
লেজিট স্ট্যাক

3

এখানে খুব সুন্দর 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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.