0
我有一個數據幀的大熊貓有許多小團體:優化大熊貓GROUPBY許多小團體
In [84]: n=10000
In [85]: df=pd.DataFrame({'group':sorted(range(n)*4),'val':np.random.randint(6,size=4*n)}).sort(['group','val']).reset_index(drop=True)
In [86]: df.head(9)
Out[86]:
group val
0 0 0
1 0 0
2 0 1
3 0 2
4 1 1
5 1 2
6 1 2
7 1 4
8 2 0
我想要做的團體一些特別的東西其中val == 1次出現但不VAL == 0。例如。僅當val == 0在該組中時,纔將組1中的1替換爲99。
但是這個尺寸呢DataFrames是相當緩慢:
In [87]: def f(s):
....: if (0 not in s) and (1 in s): s[s==1]=99
....: return s
....:
In [88]: %timeit df.groupby('group')['val'].transform(f)
1 loops, best of 3: 11.2 s per loop
通過數據幀循環更噁心,但要快得多:
In [89]: %paste
def g(df):
df.sort(['group','val'],inplace=True)
last_g=-1
for i in xrange(len(df)):
if df.group.iloc[i]!=last_g:
has_zero=False
if df.val.iloc[i]==0:
has_zero=True
elif has_zero and df.val.iloc[i]==1:
df.val.iloc[i]=99
return df
## -- End pasted text --
In [90]: %timeit g(df)
1 loops, best of 3: 2.53 s per loop
但我想如果進一步優化它可能。
任何想法如何做?
感謝
基於傑夫的回答,我得到了一個解決方案,這是非常快的。我把它在這裏,如果別人覺得有用:
In [122]: def do_fast(df):
.....: has_zero_mask=df.group.isin(df[df.val==0].group.unique())
.....: df.val[(df.val==1) & has_zero_mask]=99
.....: return df
.....:
In [123]: %timeit do_fast(df)
100 loops, best of 3: 11.2 ms per loop
我不要以爲這是我想要的。我希望僅在val 0出現在該組中時將val 1替換爲99。我修改了這個問題,試圖使這個更清楚。 – user1027953
只是更改過濾條件,很簡單 – Jeff
謝謝。我現在看到如何去做。我更新了我的問題,包括一個很好的答案。 – user1027953