Pandas 데이터 프레임의 맞춤 정렬
열에 월 이름이 포함 된 Python pandas 데이터 프레임이 있습니다.
예를 들어 사전을 사용하여 사용자 지정 정렬을 수행하려면 어떻게해야합니까?
custom_dict = {'March':0, 'April':1, 'Dec':3}
Pandas 0.15는 Categorical Series를 도입 하여이를 훨씬 더 명확하게 수행 할 수 있습니다.
먼저 월 열을 범주 형으로 만들고 사용할 순서를 지정합니다.
In [21]: df['m'] = pd.Categorical(df['m'], ["March", "April", "Dec"])
In [22]: df # looks the same!
Out[22]:
a b m
0 1 2 March
1 5 6 Dec
2 3 4 April
이제 월 열을 정렬하면 해당 목록을 기준으로 정렬됩니다.
In [23]: df.sort("m")
Out[23]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
참고 : 값이 목록에 없으면 NaN으로 변환됩니다.
관심있는 사람들을위한 오래된 답변 ...
중개 시리즈를 만들 수 있습니다 set_index
.
df = pd.DataFrame([[1, 2, 'March'],[5, 6, 'Dec'],[3, 4, 'April']], columns=['a','b','m'])
s = df['m'].apply(lambda x: {'March':0, 'April':1, 'Dec':3}[x])
s.sort()
In [4]: df.set_index(s.index).sort()
Out[4]:
a b m
0 1 2 March
1 3 4 April
2 5 6 Dec
언급했듯이 최신 팬더에서 Series에는 replace
이 작업을 더 우아하게 수행 하는 방법이 있습니다.
s = df['m'].replace({'March':0, 'April':1, 'Dec':3})
약간의 차이점은 딕셔너리 외부에 값이 있으면이 값이 올라가지 않는다는 것입니다 (단지 동일하게 유지됨).
import pandas as pd
custom_dict = {'March':0,'April':1,'Dec':3}
df = pd.DataFrame(...) # with columns April, March, Dec (probably alphabetically)
df = pd.DataFrame(df, columns=sorted(custom_dict, key=custom_dict.get))
March, April, Dec 열이있는 DataFrame을 반환합니다.
게임에 조금 늦었지만 임의의 함수를 사용하여 pandas Series, DataFrame 및 다중 인덱스 DataFrame 개체를 정렬하는 함수를 만드는 방법이 있습니다.
df.iloc[index]
위치별로 Series / DataFrame의 행을 참조하는 메서드를 사용합니다 ( df.loc
값으로 참조 하는와 비교 ). 이를 사용하여 일련의 위치 인수를 반환하는 함수가 있어야합니다.
def sort_pd(key=None,reverse=False,cmp=None):
def sorter(series):
series_list = list(series)
return [series_list.index(i)
for i in sorted(series_list,key=key,reverse=reverse,cmp=cmp)]
return sorter
이를 사용하여 사용자 지정 정렬 기능을 만들 수 있습니다. 이것은 Andy Hayden의 답변에 사용 된 데이터 프레임에서 작동합니다.
df = pd.DataFrame([
[1, 2, 'March'],
[5, 6, 'Dec'],
[3, 4, 'April']],
columns=['a','b','m'])
custom_dict = {'March':0, 'April':1, 'Dec':3}
sort_by_custom_dict = sort_pd(key=custom_dict.get)
In [6]: df.iloc[sort_by_custom_dict(df['m'])]
Out[6]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
이것은 다중 인덱스 DataFrames 및 Series 객체에서도 작동합니다.
months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
df = pd.DataFrame([
['New York','Mar',12714],
['New York','Apr',89238],
['Atlanta','Jan',8161],
['Atlanta','Sep',5885],
],columns=['location','month','sales']).set_index(['location','month'])
sort_by_month = sort_pd(key=months.index)
In [10]: df.iloc[sort_by_month(df.index.get_level_values('month'))]
Out[10]:
sales
location month
Atlanta Jan 8161
New York Mar 12714
Apr 89238
Atlanta Sep 5885
sort_by_last_digit = sort_pd(key=lambda x: x%10)
In [12]: pd.Series(list(df['sales'])).iloc[sort_by_last_digit(df['sales'])]
Out[12]:
2 8161
0 12714
3 5885
1 89238
To me this feels clean, but it uses python operations heavily rather than relying on optimized pandas operations. I haven't done any stress testing but I'd imagine this could get slow on very large DataFrames. Not sure how the performance compares to adding, sorting, then deleting a column. Any tips on speeding up the code would be appreciated!
v0.23+ Answer - sort
is deprecated.
...But that's not the point of this answer. There are multiple options to do this.
One simple method is using the output Series.map
and Series.argsort
to index into df
using DataFrame.iloc
(since argsort produces sorted integer positions); since you have a dictionary; this becomes easy.
# Setup
df
a b m
0 1 2 March
1 5 6 Dec
2 3 4 April
custom_dict = {'March': 0, 'April': 1, 'Dec': 3}
df.iloc[df['m'].map(custom_dict).argsort()]
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
If you need to sort in descending order, invert the mapping.
df.iloc[(-df['m'].map(custom_dict)).argsort()]
a b m
1 5 6 Dec
2 3 4 April
0 1 2 March
Note that this only works on numeric items. Otherwise, you will need to workaround this using sort_values
, and accessing the index:
df.loc[df['m'].map(custom_dict).sort_values(ascending=False).index]
a b m
1 5 6 Dec
2 3 4 April
0 1 2 March
More options are available with astype
(this is deprecated now), or pd.Categorical
, but you need to specify ordered=True
for it to work correctly.
# Older version,
# df['m'].astype(
# 'category', categories=sorted(custom_dict, key=custom_dict.get), ordered=True)
df['m'] = pd.Categorical(
df['m'], categories=sorted(custom_dict, key=custom_dict.get), ordered=True
)
Now, a simple sort_values
call will do the trick:
df.sort_values('m')
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
The categorical ordering will also be honoured when groupby
sorts the output.
참고URL : https://stackoverflow.com/questions/13838405/custom-sorting-in-pandas-dataframe
'IT TIP' 카테고리의 다른 글
모나 딕 파싱에 비해 응용 파싱의 이점은 무엇입니까? (0) | 2020.11.30 |
---|---|
C #은 X 분마다 스레드를 실행하지만 해당 스레드가 아직 실행되고 있지 않은 경우에만 (0) | 2020.11.30 |
web.xml의 세션 시간 초과 (0) | 2020.11.30 |
PHP는 상대 경로를 포함합니다 (0) | 2020.11.30 |
자바 8 스트림 : limit ()와 skip ()의 차이점 (0) | 2020.11.30 |