2017-01-26 5 views
1

コンテキスト:Python:多型バイナリopを実装する方法。魔法の方法?

私は毎日パンダを使用して(測定データを処理しています)、私はPythonについてもっと学びたいと思います。

これを行うには、Pandas DataFrame機能とPint ---物理量を定義、操作、操作するためのPythonパッケージの機能とを組み合わせたMyDataFrame ---を開発しています。

APIの例:

import pint 
_u = pint.UnitRegistry() 

_u("meter") 
>>> 1 meter 

type(_u("meter")) 
>>> pint.unit.build_quantity_class.<locals>.Quantity 

data = [[0,1,2,3],[4,5,6,7]] 

df = pd.DataFrame(data,columns=["time","distance"]) 

units = {"distance":_u("meter"), "time":_u("second")} 

mdf = MyDataFrame(df, units) 

mdf["speed"] = mdf["distance"]/mdf["time"] 

mdf["speed"].unit == _u("meter per second") 
>>> True 

これまでのところ、私は」

は、私はすでに__str____get/setitem__とMyDataFrameの基礎となるMySeries(パンダシリーズのラッパー)のための__truediv__を経由して、いくつかの基本的な機能を得ることができました例えば、非常に最小限の実装を保持:

class MyDataFrame: 
"""df: pandas DataFrame, units: dict of str - Pint quantity key-value pairs.""" 
    def __init__(self,df,units): 

     error_handling(df,units) 

     self.df = df 
     self.units = units 

    def __getitem__(self,key): 
     if key in units.keys(): 
      return MySeries(self.df[key],self.units[key]) 

class MySeries: 
"""series: pandas Series, units: a Pint quantity value.""" 
    def __init__(self,series,unit): 
     self.series = series 
     self.unit = unit 

    def __truediv__(self,other): 
     return MySeries(self.series/other.series,self.unit/other.unit) 

まし質問:

今、この基本的な概念を拡張して、たとえば次のようなことができます。換言すれば

mdf["speed"] * 60*_u(second) 

MySeries __mul__()多型---のみならずMySeriesもパイント数量(あるいはその逆)とMySeriesとMySeriesを乗算します。良いアプローチは何でしょうか?

__mul__(self,other)の最初のアイデアは、selfまたはotherのタイプを確認することでした。しかし、Python(here)の多態性についてもっと読んでみると、他の人がこのような多型バイナリ操作をどのように実装するのか不思議に思っていました。

いくつかの説明をする必要があるかどうか教えてください。

PS:脇に。私は、このような

def __getitem__(self,key): 
    return self.series[key] 

def notnull(self): 
    return self.series.notnull() 

すべての通常のパンダ方法はMyDataFrame/MySeriesクラスのパンダの一部に呼び出しをリダイレクト上の任意のアドバイスとしてラッパーを書くパンダ構文I`mを模倣しようとしていることに気づきますか?

はところで、私は

答えて

0

は残念ながら、他の方法がない...それは私がPythonのドキュメントを詳細に調べるための時間であることをヒッチを取得します。多態性はすべてのタイプのPandasに対してmulを実装することで既に使用されています。したがって、対応する演算子は最初の引数の型で動作が異なります。しかし、2番目の引数では、型をチェックする必要があります。静的言語では、によって第2引数型に基づいた関数がオーバーロードされますが、Pythonではisinstanceを使用する必要があります。 Pythonの標準ライブラリでさえ、ソースを見るとそのアプローチを使用します。

+0

ありがとうございます。 Pintメインクラスの型を扱うのが難しい場合、 'isistance'を介したハンドリングは問題ありません。 'type(_u(" meter "))'は 'pint.unit.build_unit_classを返します。 .Unit'ここで私は 'Unit'のようなものを返すと期待しています。どんな手掛かり? – balletpiraat

+1

'type'を使わないでください。サブクラスは無視されます。'でisinstance(_u(「メートル」)、ユニット)'代わり –

+0

すでに多くを明確にそれは、しかし、上記のリターンは '名「ユニットは」私は'輸入pint'は、Pythonに認識させるには十分ではないと思わせたdefined'されていない使用しますPintの 'Unit'クラスのものです。ところで、私はJupyterノートブックで仕事をしています。解決策は、 'pint import Unit'と同じようなものでしょうか? – balletpiraat

関連する問題