2017-02-08 4 views
2

私は、すべての行が会社で、列が月ごとの収益であるデータフレームを持っています。パンダ:チャーンの発生場所を動的に計算する

import pandas as pd 
from io import StringIO 

data=''' 
Company 1 2 3 4 5 6 7 8 9 10 11 12 CHURN 
Dell  nan nan nan 600 550 620 nan nan 300 100 200 50 
Sony  740 720 780 700 250 140 20 nan nan nan nan nan 
Toshiba nan nan nan nan 400 550 nan 500 nan 40 50 nan 
Apple  nan 300 350 300 400 500 nan nan nan nan nan nan 
Acer  150 200 250 200 50 50 40 35 30 20 10 nan''' 

df=pd.read_csv(StringIO(data),delimiter='\s+') 

これらの会社が(部分的に)解約する場合は、計算する必要があります。私の定義は以下の通りです。

  1. 収益は少なくとも4ヶ月連続している必要があります。
  2. 2か月間、収入は特定の地点を下回っている必要があります。
  3. この特定のポイントは、その前の期間である の平均収入の50%であり、その4ヶ月連続で始まります。
  4. チャーンの価値は、収益が最初に の50%ポイントを下回った月になります。

結果は次のようになります。

Company 1 2 3 4 5 6 7 8 9 10 11 12 CHURN 
-------------------------------------------------------------------------------- 
Dell  nan nan nan 600 550 620 nan nan 300 100 200 50 nan 
Sony  740 720 780 700 250 140 20 nan nan nan nan nan 5 
Toshiba nan nan nan nan 400 550 nan 500 nan 40 50 nan nan 
Apple  nan 300 350 300 400 500 nan nan nan nan nan nan 7 
Acer  150 200 250 200 50 50 40 35 30 20 10 nan 5 

編集: まあ、私はiloc[]のために行くとローマPekarは、より良い何かを思い付いた前にループ

ために入れ子にされました。問題は解決しました。あなたはpandas.Series.rollingで簡単にそれを行うことができますが、カスタム関数とpandas.DataFrame.applyでそれを行うことができます間違いなく場合

+0

あなたが持っているものは何でもしようと入力してください。 – blacksite

+0

書き出されたデータフレームを提供できますか? – Chuck

+1

私は編集しました。これはあなたが意味することですか?申し訳ありませんが、私はまだそれに取り組んでいます。私は擬似コードの束を持っていますが、私は今のところiterrows()よりはるかに進んでいません。それにもかかわらず作業。 – Duudsrednaz

答えて

1

わからない:

>>> def worker(x): 
...  for i in range(1, len(x) - 6): 
...   d = x[i:i+4] 
...   if not d.isnull().values.any(): 
...    if x[i+4:i+6].fillna(0).max() < d.mean()/2: 
...     return i+4 
... 
>>> df.apply(worker, axis=1) 
0 NaN 
1 5.0 
2 NaN 
3 7.0 
4 5.0 
+0

ありがとうございます。私は、すべてをループするだけでなく、何か良いものがなければならないことを知っていました。私は 'Series.rolling'を調べます。それが速ければ、私は更新します。 – Duudsrednaz