[PYTHON] PANDAS의 SQL과 유사한 창 기능 : Python Pandas Dataframe의 행 번호 매기기
PYTHONPANDAS의 SQL과 유사한 창 기능 : Python Pandas Dataframe의 행 번호 매기기
나는 SQL 배경에서 왔고 다음 데이터 처리 단계를 자주 사용합니다.
전의:
df = pd.DataFrame({'key1' : ['a','a','a','b','a'],
'data1' : [1,2,2,3,3],
'data2' : [1,10,2,3,30]})
df
data1 data2 key1
0 1 1 a
1 2 10 a
2 2 2 a
3 3 3 b
4 3 30 a
나는 PANDAS를이 SQL 창 함수와 동등하게 수행하는 방법을 찾고있다.
RN = ROW_NUMBER() OVER (PARTITION BY Key1, Key2 ORDER BY Data1 ASC, Data2 DESC)
data1 data2 key1 RN
0 1 1 a 1
1 2 10 a 2
2 2 2 a 3
3 3 3 b 1
4 3 30 a 4
나는 '파티션'이없는 곳에서 일하게 된 다음을 시도했다.
def row_number(frame,orderby_columns, orderby_direction,name):
frame.sort_index(by = orderby_columns, ascending = orderby_direction, inplace = True)
frame[name] = list(xrange(len(frame.index)))
이 아이디어를 파티션 (팬더의 그룹)과 함께 사용하도록 확장하려고 시도했지만 다음은 작동하지 않았습니다.
df1 = df.groupby('key1').apply(lambda t: t.sort_index(by=['data1', 'data2'], ascending=[True, False], inplace = True)).reset_index()
def nf(x):
x['rn'] = list(xrange(len(x.index)))
df1['rn1'] = df1.groupby('key1').apply(nf)
하지만이 작업을 수행 할 때 많은 NaN이 생겼습니다.
이상적으로, sql의 창 함수 기능을 복제하는 간결한 방법이 있습니다. (창 기반 집계를 알아 냈습니다 ... 판다에있는 하나의 라이너입니다.) 누군가가 나에게 가장 관용적 인 방법을 공유 할 수 있습니까? PANDAS에서 이처럼 숫자 행을?
해결법
-
==============================
1.rankby 메서드와 함께 groupby를 두 번 사용하여이 작업을 수행 할 수 있습니다.
rankby 메서드와 함께 groupby를 두 번 사용하여이 작업을 수행 할 수 있습니다.
In [11]: g = df.groupby('key1')
동일한 데이터를 공유하는 값을 동일한 RN에 부여하려면 min 메소드 인수를 사용하십시오.
In [12]: g['data1'].rank(method='min') Out[12]: 0 1 1 2 2 2 3 1 4 4 dtype: float64 In [13]: df['RN'] = g['data1'].rank(method='min')
그런 다음 이들 결과를 그룹화하여 data2와 관련하여 순위를 추가하십시오.
In [14]: g1 = df.groupby(['key1', 'RN']) In [15]: g1['data2'].rank(ascending=False) - 1 Out[15]: 0 0 1 0 2 1 3 0 4 0 dtype: float64 In [16]: df['RN'] += g1['data2'].rank(ascending=False) - 1 In [17]: df Out[17]: data1 data2 key1 RN 0 1 1 a 1 1 2 10 a 2 2 2 2 a 3 3 3 3 b 1 4 3 30 a 4
이 작업을 수행하는 기본 방법이되어야하는 것처럼 느껴집니다 (잘 될 수도 있습니다! ...).
-
==============================
2.당신은 또한 sort_values (), groupby () 그리고 마지막으로 cumcount () + 1 :
당신은 또한 sort_values (), groupby () 그리고 마지막으로 cumcount () + 1 :
df['RN'] = df.sort_values(['data1','data2'], ascending=[True,False]) \ .groupby(['key1']) \ .cumcount() + 1 print(df)
수율 :
data1 data2 key1 RN 0 1 1 a 1 1 2 10 a 2 2 2 2 a 3 3 3 3 b 1 4 3 30 a 4
판다 0.18로 테스트 한 PS
-
==============================
3.transform과 rank를 함께 사용할 수 있습니다. 예제가 있습니다.
transform과 rank를 함께 사용할 수 있습니다. 예제가 있습니다.
df = pd.DataFrame({'C1' : ['a','a','a','b','b'], 'C2' : [1,2,3,4,5]}) df['Rank'] = df.groupby(by=['C1'])['C2'].transform(lambda x: x.rank()) df
자세한 정보는 Pandas Rank 방법을 살펴보십시오.
-
==============================
4.pandas.lib.fast_zip ()은 배열리스트로부터 튜플 배열을 생성 할 수 있습니다. 이 함수를 사용하여 튜플 시리즈를 만든 다음 순위를 매길 수 있습니다.
pandas.lib.fast_zip ()은 배열리스트로부터 튜플 배열을 생성 할 수 있습니다. 이 함수를 사용하여 튜플 시리즈를 만든 다음 순위를 매길 수 있습니다.
values = {'key1' : ['a','a','a','b','a','b'], 'data1' : [1,2,2,3,3,3], 'data2' : [1,10,2,3,30,20]} df = pd.DataFrame(values, index=list("abcdef")) def rank_multi_columns(df, cols, **kw): data = [] for col in cols: if col.startswith("-"): flag = -1 col = col[1:] else: flag = 1 data.append(flag*df[col]) values = pd.lib.fast_zip(data) s = pd.Series(values, index=df.index) return s.rank(**kw) rank = df.groupby("key1").apply(lambda df:rank_multi_columns(df, ["data1", "-data2"])) print rank
결과:
a 1 b 2 c 3 d 2 e 4 f 1 dtype: float64
from https://stackoverflow.com/questions/17775935/sql-like-window-functions-in-pandas-row-numbering-in-python-pandas-dataframe by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Python + Selenium + PhantomJS에서 PDF로 렌더링 (0) | 2018.10.27 |
---|---|
[PYTHON] 사용자 정의 메트릭을 사용하여 Sklearn kNN 사용 (0) | 2018.10.27 |
[PYTHON] 파이썬에서 크로스 플랫폼 콘솔 앱용 저주 라이브러리 (0) | 2018.10.27 |
[PYTHON] Scikit-Learn에서 의사 결정 트리 시각화 (0) | 2018.10.27 |
[PYTHON] 파이썬에서 z- 스코어와 그 반대로의 확률 (0) | 2018.10.27 |