2017-03-01 5 views
0

上で差分を広め、私は(必ずしもソートされていない)numpyの配列を持っている:numpyの/パンダの差分:均等に囲まれたナン要素

[2.0, 3.0, nan, nan, nan, 5.0] 

私はこのアレイ上の差異を計算します。最後の要素5と2番目の要素3との間の差は2です。この2の差を私のnumpy配列の囲まれた要素に渡したいと思います。私がnumpy.diffを試してみたら(私もマスクされた配列を使ってみました)、結果は

[nan, 1, nan, nan, nan, nan]です。結果は以下のようになります。

[nan, 1, 0.5, 0.5, 0.5, 0.5] 

UPDATE:

は、私は上記の特定のケースのための答えを得たが、与えられた答えは、より一般的な形で有効ではありません。例えば、私たちが後ろに/先導するnanを持っている場合と、代わりにnanと値を持っている場合です。例:入力の違い[i]と入力し、[I-1]〜あなたが何をしようとしていることは出力をマップであるという仮定の下では

[nan, nan, 2.0, 3.0, nan, nan, nan, 5.0, nan, 6.0, nan] 
+0

、NaNを除くには、ソートされた入力配列のですか?また、出力配列もソートされているように見えます。 アイデアは出力[i]は入力[i]と入力[i-1]のdiffの平均ですが、特別な場合はnansですか? – JawguyChooser

+0

最初の質問:いいえ、配列は必ずしも[5、11、4、nan、2]のように並べ替えるわけではありません。 2番目の質問:はい、入力[i-1]が非入力であれば入力[i-2]をチェックし、入力[1-2]がナンでなければ入力[i]と入力[i-2 ]を入力[i-1]と入力[i]に等しく上乗せする。 –

+0

アップデートケースの予想される出力はどのくらいですか? – JawguyChooser

答えて

1

おかげで、私はパンダに探していると、彼らはこの一般的な問題を解決するためのボックスのメソッドの外に持っている:

は、データフレームを補間し、差分を取る、データフレームに配列を変換します。

import pandas as pd 
    array = [nan, nan, 2.0, 3.0, nan, nan, nan, 5.0, nan, 6.0, nan] 
    df = pd.DataFrame(array) 
    interpolation = df.interpolate() 
    diff = interpolation.diff() 

結果は次のとおりです。だから、

[NaN, NaN, NaN, 1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0] 
1

[i]を、そして特殊なケースでNaNを、あなたはNaNを越えてその違いを配布したい、それがアイデアだ場合、私は、これはあなたが欲しいものだと思う:

import numpy as np 

def arrdiffs(a): 
    out = np.array(np.zeros(len(a))) 
    diff=np.nan 
    difflen=0 
    for i,e in enumerate(a): 
     if i==0: 
      # in the first cell we always output nan 
      out[i]=np.nan 
     elif np.isnan(a[i]): 
      # when the input is nan, just increase difflen 
      difflen+=1 
     elif np.isnan(a[i-1]): 
      # when the previous input is nan, but this one isn't 
      # distribute the diff across the previous cells and this one 
      difflen+=1 
      m=float(abs(a[i]-diff)) 
      for j in range(i-difflen+1,i+1): 
       out[j]=m/difflen 
      difflen=0 
      diff=a[i] 
     else: 
      # othewise simply do the diff locally between this cell and 
      # previous 
      out[i]=abs(a[i]-a[i-1]) 
      diff=a[i] # write down diff in case the next input cells are nan 
      difflen=0 

    return out 

a=np.array([2.0,3.0,np.nan,np.nan,np.nan,5.0]) 
print arrdiffs(a) 

編集:4つのスペースのタブに切り替え代わりの2、IF /他に平坦化elifs、各ブランチに コメントが追加されました。

私はこれを実行すると、私はあなたの期待出力を得る:

$ python arrdiffs.py 
[ nan 1. 0.5 0.5 0.5 0.5] 

編集を:おそらく我々だけで、我々はNaNを一連で始まる場合を考慮してnp.nanする差分の初期値を切り替えます少なくとも初期値に達するまでナノを出力する。目標が何であるかを明確にするためにOPにお尋ねください。 [i-1]がnanであるがa [i]がそうでない場合(これはバグだった)、割り当て差分をa [i]に切り替えた。

[np.nan, np.nan, 2.0, 3.0, np.nan, np.nan, np.nan, 5.0, np.nan, 6.0, np.nan] 

このアップデートコードを示します::OPが提供する新しいテストケースで

>>> [ nan nan nan 1. 0.5 0.5 0.5 0.5 0.5 0.5 0. ] 

これはOPが望んでいますか?説明を探しています。

作業を行う必要があります
+0

jをループしていた最初に投稿したときにバグがありました。私はこれを今修正した。現在のバージョンを確認してください。jをループして、i-difflen + 1からi-difflenに移動したい場合 – JawguyChooser

1

In [1]: import pandas as pd 

In [2]: import numpy as np 

In [3]: a = [2.0, 3.0, np.nan, np.nan, np.nan, 5.0] 

In [4]: s = pd.Series(a) 

In [5]: result = s.reset_index()\ 
    ...:   .dropna()\ 
    ...:   .diff()\ 
    ...:   .pipe(lambda x: x[0]/x['index'])\ 
    ...:   .reindex(s.index)\ 
    ...:   .fillna(method='bfill') 

In [6]: result[0] = np.nan 

In [7]: result 
Out[7]: 
0 NaN 
1 1.0 
2 0.5 
3 0.5 
4 0.5 
5 0.5 
dtype: float64 
+0

これは彼が探している答えではないと思います。あなたは彼の期待される出力をOPで見る。 – JawguyChooser

+0

私が書いたように、最初の要素にNAを割り当てる必要があります。私はこれが簡単だと思ったが、望むならコード例にそれを追加する –

1

私は単に最初ナンさんを補間します。このようにして、これらの2つのステップを素早く分離して補間の方法を変更するなどの作業を容易にします。もっと派手な補間については

import numpy as np 

a = np.array([2.0, 3.0, np.nan, np.nan, np.nan, 5.0]) 
x = np.arange(a.size) 

a_filled = np.interp(x, x[np.isfinite(a)], a[np.isfinite(a)]) 

np.diff(a_filled) 

# results in 
array([ 1. , 0.5, 0.5, 0.5, 0.5]) 

、パンダは良い選択肢かもしれないが、それはまた、データフレームのための.diff()方法があります。ルトガーKassiesへ

関連する問題