2016-08-05 9 views
1

私はいくつかのユーザ入力で生データの束を読み込み、それをPandasシリーズにコンパイルする関数を持っています。下の例では、私はそれをcreate_dataと呼んでおり、長さがnのランダム系列を構築しています。pandasシリーズからクラスオブジェクトを作成してメソッドを適用する

>>> def create_data(n): 
...  return pd.Series(np.random.randint(1, 100, n)) 
... 
>>> 
>>> function_result=create_data(10) 
>>> function_result 
0 73 
1 91 
2 31 
3 44 
4 19 
5 30 
6 42 
7 56 
8 69 
9 70 
dtype: int32 

次に、このシリーズに適用したい機能セットがあります。この例では、系列とその1次の差との間の相関を計算するものを作成します。

>>> def temporal_corr(x): 
...  return pd.concat([x, x.shift()], 1).corr().iloc[0, 1] 
... 

私は明らかにただの関数を呼び出すことにより、シリーズに適用することができます...

>>> temporal_corr(function_result) 
0.38714413906049816 

しかし、のは私がこのシリーズに使用する、いくつかの異なる機能を持っているとしましょう。関数create_dataを使用してオブジェクトを構築するクラスを作成し、そのクラス内にメソッドとして適用できる関数のセットを持たせることは意味がありますか(または可能でしょうか)。私はクラスを作成し、この関数を以下で定義します。

>>> class myobj: 
...  def __init__(self, myobj): 
...   self.myobj = myobj 
...  
...  def temporal_corr(self): 
...   return pd.concat([self.myobj, self.myobj.shift()], 1).corr().iloc[0, 1] 
... 
>>> a = myobj(function_result) 
>>> a.temporal_corr() 
0.38714413906049816 

機能create_dataの結果として作成さmyobjクラスオブジェクトを持つための最良の方法は何ですか?私はcreate_dataに電話し、その結果をtemporal_corr()と呼ぶことができるオブジェクトにしたいと考えています。

import pandas as pd 
from numpy.random import randint 

class mySeries(pd.Series): 

    def __init__(self, n): 
     super().__init__(randint(0, 100, n)) # initialize series 

    # Add your custom methods: 
    def temporal_corr(self): 
     return pd.concat([self, self.shift()], 1).corr().iloc[0, 1] 

その後、create_dataをすることができ、あなたの工場の機能:基本的に

+0

私はこの質問をよく理解していません。 'create_data'が' myobj'インスタンスを返すようにしたいのであれば、それだけではありません: 'create create_data(n):return myobj(pd.Series(np.random.randint(1、100、n)))' – Blckknght

+0

なぜ地球上でそれをしたいのですか?これはコードをより複雑にし、利益をもたらさない。 – BlackJack

答えて

0

、私はあなたが次の操作を行うために探していると思います。たとえば、次のように私はそれを使用したい:

In [2]: a = create_data(10) # `a` is now an instance of MyObjMaker 

In [4]: type(a) # proof that `a` is now an instance of MyObjMaker 
Out[4]: __main__.MyObjMaker 

In [5]: a.temporal_corr() # `temporal_corr` works 
Out[5]: -0.18294239972101703 

ジムのソリューションは、あまりにも問題ないはずですが、それpd.Seriesのオフサブクラスは - pd.Seriesが、その後はポイントがありませんで、あなたは他のすべてのメソッドを必要としない場合それをサブクラス化する。

+0

'__init __()'だけで、1つの値をカプセル化し、このような1つのメソッドを持つ場合、クラスはありません。これは単なる複雑すぎる方法で書かれた関数です。このような構成は何ですか? 'create_data()'も意味をなさない。この関数の効果は 'MyObjMaker'のエイリアスに過ぎません。これは' create_data = MyObjMaker'として簡単に書くことができます。 – BlackJack

+0

@BlackJackあなたがQ/Aを慎重に読んだら、これは尋問者が解決しようとしていたものです。この質問はPythonやPythonのスタイルではなく、非常に特殊なものだったので、なぜ彼らが何か特定のやり方をしているのだろうと私は思っていません。また、あなたの 'create_data = MyObjMaker'は間違っています。これにより 'create_data'も' class'になります。私が持っている方法では、それは 'MyObjMaker'型の保証されたインスタンスを返します。 – alichaudry

+0

コメントはPythonやスタイルとは関係ありません。 Java(ラムダ式の前)のように、言語があなたを強制しない限り、単純な関数を無用なクラスとして整えるのは意味がありません。どうすれば 'create_data'のより単純な定義が別のインスタンスを返すのでしょうか?たぶん 'MyObjMaker'が' __new __() 'を実装しているかもしれませんが、それはあなたの関数に同じように影響します。 – BlackJack

1

あなたはSeriesのように動作しますが、よりは、そう、ちょうどpd.Seriesから継承するクラスを作成特化されたオブジェクトを探していますあなたが拡張し、必要に応じてチェックを追加することができます

def create_data(n): 
    return mySeries(n) 

:あなたの専門Seriesオブジェクト用。

import pandas as pd 
import numpy as np 


class MyObjMaker(object): 

    def __init__(self, n): 
     self.myobj = pd.Series(np.random.randint(1, 100, n)) 

    def temporal_corr(self): 
     return pd.concat([self.myobj, self.myobj.shift()], 1).corr().iloc[0, 1] 


def create_data(n): 
    return MyObjMaker(n) 

ここで、機能create_dataはクラスからオブジェクトを作成し、それはあなたのtemporal_corr機能を持っている:私が正しくあなたの質問を理解していれば

関連する問題