私はこれをいつか行っていて、うまくいかないようです。私は、次のような2つのレベルのマルチインデックスデータフレームを扱っています:マルチインデックスデータフレーム内で連続したイベントをカウントするパンダ
def data():
data = {'date': pd.Series(['2016-1-1', '2016-1-1', '2016-1-1',
'2016-1-2', '2016-1-2', '2016-1-2',
'2016-1-3', '2016-1-3', '2016-1-3',
'2016-1-4', '2016-1-4', '2016-1-4',
'2016-1-5', '2016-1-5', '2016-1-5']),
'group': pd.Series(['groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC',
'groupA', 'groupB', 'groupC']),
'series1': pd.Series([1, 2, 3,
1, 2, 3,
1, 2, 3,
1, 3, 4,
2, 3, 4]),
'series2': pd.Series([1, 3, 4,
2, 3, 3,
2, 4, 2,
1, 2, 3,
1, 2, 3])}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df.set_index(['date', 'group'], inplace=True)
return df
私は3つの条件の1つを指定する列を持っています。コードのこの部分を書くためのより簡潔な方法があるかもしれませんが、これは私の問題ではありません。
def add_cond(df):
df['1minus2'] = df['series1'] - df['series2']
# first condition
mask1 = df['series1'] < df['series2']
df.loc[mask1, 'result'] = 'less'
# second condition
mask2 = df['series1'] > df['series2']
df.loc[mask2, 'result'] = 'greater'
# third condition
mask3 = df['series1'] == df['series2']
df.loc[mask3, 'result'] = 'equal'
return df
私の問題は、毎日の連続条件の数をカウントする列を追加したいということです。私はgroupby
とcumcount
のいくつかの異なる実装を試して、私はすべての条件の累積カウントを得ることができますが、私はそれらが日付インデックスが連続していないときにリセットしたい。
以下、私が試したいくつかの関連記事をリストアップしました。私はPandas: conditional rolling countの2番目の答えは動作すると思ったが、複数の列があるのでここでは動作しないようなtransform
メソッドを使用する。
ポストFinding consecutive segments in a pandas data frameに概略が記載されている戦略に従って、私はのnumpy arrays
を作成し、日付とグループのインデックス値と「結果」列のデータを含むコードを作成しました。私はこのような方法でこのdfをスライスして、連続する各グループを数え、その結果を元のdfにマージすることができると考えています。
df1 = df.reset_index(level=['date','group']).groupby(['result']).apply(np.array)
出力は次のようになります。
1
1
1
1
2
1
2
3
1
1
1
2
1
2
3
それは、累積の連続した条件は、階層DF構造で満たされているかどうかを確認するために少し難しいですが、私はDFスタックを解除場合、それは私が達成しようとしているものを見るためにはるかに簡単です。おそらく、unstack
を使用して、私が探している結果を与えるような方法でデータを方向付ける方法がありますか?
df['result'].groupby(['date','group']).head().unstack()
Out[9]:
group groupA groupB groupC
date
2016-01-01 equal less less
2016-01-02 less less equal
2016-01-03 less less greater
2016-01-04 equal greater greater
2016-01-05 greater greater greater
私はあなたが探している正確な力学に関する多くの明確にすることができると思います。 'date'カラムと何が関係しているのかは分かりません(関連性がありますか)。また、 'np.sign(series1 - series2)'が 'add_cond()'を行う良い方法であることに注意してください。 –
ありがとう@ジョン・ツィンク私はどのように明らかにするかを見ていきます。元のコードではnp.signを使用していましたが、ゼロが記号の変化としてどのように評価され、ラムダ内で使用したときに、私が望むように動作させることができなかったのが好きではありませんでした。 – Greg