2016-10-28 2 views
3

데이터 프레임에 값에 따라 해당 행을 분류해야하는 숫자 열이 있습니다. 예를 들어, 팬더 : 확장 분위수를 기반으로 카테고리를 만드는 방법은 무엇입니까?

id value 
1 2.0 
2 3.0 
3 4.5 
4 5.5 

는 그 행 앞에 온 행의 분위수 값을 기준으로 group 변수 새로운 카테고리가 필요합니다. 따라서 id=2의 경우, Quantile 계산에서 행 1과 2를 고려합니다. 그런 다음 분류를 수행하십시오 :

if value > quantile(90%)        category = 'Very High' 
if value > quantile(75%) & value <= quantile(90%) & category = 'High' 
if value > quantile(25%) & value <= quantile(75%) & category = 'Normal' 
if value <= quantile(25%)        category = 'Low' 

어떻게 그런 분위수를 계산하고 비교합니까?

+0

당신이 여러 dataframe 출력하거나 일을 기대하고,이 각각의 값에 "매우 높음"반환합니다 같은 느낌, 우리에게 예상되는 출력을 제공 할 수 있습니다 ? –

답변

1

어쩌면 나는 그 질문을 잘 이해하지 못할 수도 있지만 시리즈가 항상 증가하고 있기 때문에 마지막 값의 몫은 항상 1이 될 것이므로 출력은 항상 "매우 높음"이어야합니다.

각 반복에 대해 시리즈를 만들고 있기 때문에 이것은 효율적이지 않지만 트릭을 수행합니다. 당신은 백분위 수를 계산하기 위해 scipy에서 무언가로 적용 함수를 변경할 수 있습니다. 프로세스 속도가 향상됩니다.

DataFrame.expanding()에는 rank() 메서드가 없기 때문에 이것이 모두입니다. 그것이 가능하다면 그것은 매우 솔직하게 진행되었을 것입니다. scipy 종속성

def ranking(x): 
    return pd.Series(x).rank(pct=True).values[-1] 

ranked = sx.expanding().apply(lambda x: ranking(x)) 
pd.cut(ranked, (0, 0.25, 0.75, 0.90, 1), labels=['low', 'Normal', 'High', 'Very High']) 
Out[97]: 
0 Very High 
1 Very High 
2 Very High 
3 Very High 
dtype: category 
Categories (4, object): [low < Normal < High < Very High] 

빠른 솔루션 :

from scipy.stats import rankdata 
ranked = sx.expanding().agg(lambda x: rankdata(x)[-1]/len(x)) 

In[108]: import timeit 
In[109]: %timeit sx.expanding().agg(lambda x: rankdata(x)[-1]/len(x)) 
1000 loops, best of 3: 611 us per loop 
In[110]: %timeit sx.expanding().apply(lambda x: ranking(x)) 
1000 loops, best of 3: 1.15 ms per loop 
+0

어쩌면이게 더 빠를거야.'scipy.stats import rankdata rank = df.expanding() .gg (람다 x : rankdata (x) [- 1]/len (x))' –

+0

예 –

관련 문제