我有一個數據幀以多指標的表現基本上是一個二元矩陣:提高重複GROUPBY操作
day day01 day02
session session1 session2 session3 session1 session2 session3
0 1 0 0 0 0 0
1 0 0 1 1 1 0
2 1 1 1 0 0 1
3 1 0 0 1 0 0
4 1 0 1 0 0 0
從這個數據幀,我需要計算每日的資金用於每行:
day01 day02
0 1 0
1 1 2
2 3 1
3 1 1
4 2 0
並得到0,1秒的(值計數)這筆金額的數目...:我需要做此F
0 2
1 5
2 2
3 1
或會話。每一行會議和:
session1 session2 session3
0 1 0 0
1 1 1 1
2 1 1 2
3 2 0 0
4 1 0 1
,並獲得價值數:
0 5
1 8
2 2
爲基準,這是df.groupby(level='day', axis=1).sum().stack().value_counts()
(和df.groupby(level='session', axis=1).sum().stack().value_counts()
)的結果。 DataFrame在模擬退火算法的每次迭代中都會發生變化,並重新計算這些計數。當我剖析代碼時,我發現在groupby操作上花費了大量的時間。
我試着保存groupby對象,並在每次迭代中對這些對象進行總計,但改進大約爲10%。下面的代碼創建一個更大的數據幀(類似於一個我):
import numpy as np
import pandas as pd
prng = np.random.RandomState(0)
days = ['day{0:02d}'.format(i) for i in range(1, 11)]
sessions = ['session{}'.format(i) for i in range(1, 5)]
idx = pd.MultiIndex.from_product((days, sessions), names=['day', 'session'])
df = pd.DataFrame(prng.binomial(1, 0.25, (1250, 40)), columns=idx)
在我的電腦,以下兩種方法分別以3.8S和3.38s。
def try1(df, num_repeats=1000):
for i in range(num_repeats):
session_counts = (df.groupby(level='session', axis=1, sort=False)
.sum()
.stack()
.value_counts(sort=False))
daily_counts = (df.groupby(level='day', axis=1, sort=False)
.sum()
.stack()
.value_counts(sort=False))
return session_counts, daily_counts
def try2(df, num_repeats=1000):
session_groups = df.groupby(level='session', axis=1, sort=False)
day_groups = df.groupby(level='day', axis=1, sort=False)
for i in range(num_repeats):
df.iat[0, 0] = (i + 1) % 2
session_counts = session_groups.sum().stack().value_counts(sort=False)
daily_counts = day_groups.sum().stack().value_counts(sort=False)
return session_counts, daily_counts
%time try1(df)
Wall time: 3.8 s
%time try2(df)
Wall time: 3.38 s
注意:函數中的循環僅用於計時。對於第二個函數,爲了獲得正確的時序,我需要修改DataFrame。
我目前正在研究另一種方法,直接反映DataFrame中的更改計數沒有重新計算組,但我還沒有成功。跟蹤受影響的行並更新保存的數據幀結果變慢。
有沒有辦法提高這些groupby操作的性能?
是否在T elems的順序窩產品很重要?另外,兩個產出的指標是否重要? – Divakar
不,只要我知道有多少個0,1等,那麼順序(或哪個數據結構就包含這些信息)並不重要。我應該知道哪一個對應於0,哪一個對應於1。 – ayhan