私は、次のことをしようとしている非正規のタイムスタンプによって索引付けされた非常にまばらなデータフレーム(1行につき1つの非ゼロ値のみ)を持っています。パンダの行フィルタ/クロス集計をローリングするには?
与えられた列の0以外の値について、与えられたtimedelta内の他の列の他の非ゼロ値の数を数えたいと思います。ある意味では、rolling cross_tabのようなものを計算しようとしています。
これまでの私のソリューションは、スライシングとローリングを使用してこれを行う方法を理解していないので、醜いですし、遅いです。
delta = 1
values = pd.DataFrame(0,index= df.columns,columns= df.columns)
for j in df.columns:
for i in range(len(df[df[j]!=0].index)-1):
#min is used to avoid overlapping
values[j] +=df[(df.index<min((df[df[j]!=0].index + pd.tseries.timedeltas.to_timedelta(delta, unit='h'))[i],df[df[j]!=0].index[i+1]))&(df.index>=df[df[j]!=0].index[i])].astype(bool).sum()
values = values.T
とおもちゃ例のデータフレームである:
df = pd.DataFrame.from_dict({"2016-01-01 10:00.00":[0,1],
"2016-01-01 10:30.00":[1,0],
"2016-01-01 12:00.00":[0,1],
"2016-01-01 14:00.00":[1,0]},
orient="index")
df.columns=['a','b']
df.index = pd.to_datetime(df.index)
a b
2016-01-01 10:00:00 0 1
2016-01-01 10:30:00 1 0
2016-01-01 12:00:00 0 1
2016-01-01 14:00:00 1 0
所望の出力は(カウントがはtimedeltaに依存して)次のようになります。それはのようなものが見えます
a b
a 1 0
b 1 1
ありがとうございました。 – alkaet
タイムスタンプはソートされています(私が述べたはずです)。 これは私が望むものとは少し異なります。私は少し明確にしようとします。 の変更の1時間以内に発生する列bの変化の数をカウントしたいと思います。私の例では、aが1時間以内に1回変化します - 行b列aの出力でカウントされます(対角線は元のデータフレームの各列の値の変更の数だけ)。 あなたの答えは、正しく理解すれば、1つの列の値のローリング合計に過ぎません。 – alkaet