sort reorder index has groupby columns column attribute python sorting pandas

reorder - sort column python



clasificación por una lista personalizada en pandas (2)

Después de leer: http://pandas.pydata.org/pandas-docs/version/0.13.1/generated/pandas.DataFrame.sort.html

Todavía no puedo entender cómo ordenar una columna por una lista personalizada. Obviamente, el orden predeterminado es alfabético. Voy a dar un ejemplo. Aquí está mi marco de datos (muy abreviado):

Player Year Age Tm G 2967 Cedric Hunter 1991 27 CHH 6 5335 Maurice Baker 2004 25 VAN 7 13950 Ratko Varda 2001 22 TOT 60 6141 Ryan Bowen 2009 34 OKC 52 6169 Adrian Caldwell 1997 31 DAL 81

Quiero poder ordenar por Jugador, Año y luego Tm. El orden predeterminado por jugador y año está bien para mí, en orden normal. Sin embargo, no quiero que el Equipo esté ordenado alfabéticamente b / c Quiero TOT siempre en la parte superior.

Aquí está la lista que he creado:

sorter = [''TOT'', ''ATL'', ''BOS'', ''BRK'', ''CHA'', ''CHH'', ''CHI'', ''CLE'', ''DAL'', ''DEN'', ''DET'', ''GSW'', ''HOU'', ''IND'', ''LAC'', ''LAL'', ''MEM'', ''MIA'', ''MIL'', ''MIN'', ''NJN'', ''NOH'', ''NOK'', ''NOP'', ''NYK'', ''OKC'', ''ORL'', ''PHI'', ''PHO'', ''POR'', ''SAC'', ''SAS'', ''SEA'', ''TOR'', ''UTA'', ''VAN'', ''WAS'', ''WSB'']

Después de leer el enlace anterior, pensé que esto funcionaría, pero no funcionó:

df.sort([''Player'', ''Year'', ''Tm''], ascending = [True, True, sorter])

Todavía tiene ATL en la parte superior, lo que significa que se ordenó alfabéticamente y no de acuerdo con mi lista personalizada. Cualquier ayuda realmente sería muy apreciada, simplemente no puedo resolver esto.


A continuación se muestra un ejemplo que realiza una clasificación lexicográfica en un marco de datos. La idea es crear un índice numérico basado en la clasificación específica. Luego realizar una ordenación numérica basada en el índice. Se agrega una columna al marco de datos para hacerlo, y luego se elimina.

import pandas as pd # Create DataFrame df = pd.DataFrame( {''id'':[2967, 5335, 13950, 6141, 6169],/ ''Player'': [''Cedric Hunter'', ''Maurice Baker'' ,/ ''Ratko Varda'' ,''Ryan Bowen'' ,''Adrian Caldwell''],/ ''Year'': [1991 ,2004 ,2001 ,2009 ,1997],/ ''Age'': [27 ,25 ,22 ,34 ,31],/ ''Tm'':[''CHH'' ,''VAN'' ,''TOT'' ,''OKC'' ,''DAL''],/ ''G'':[6 ,7 ,60 ,52 ,81]}) # Define the sorter sorter = [''TOT'', ''ATL'', ''BOS'', ''BRK'', ''CHA'', ''CHH'', ''CHI'', ''CLE'', ''DAL'',''DEN'',/ ''DET'', ''GSW'', ''HOU'', ''IND'', ''LAC'', ''LAL'', ''MEM'', ''MIA'', ''MIL'',/ ''MIN'', ''NJN'', ''NOH'', ''NOK'', ''NOP'', ''NYK'', ''OKC'', ''ORL'', ''PHI'',/ ''PHO'', ''POR'', ''SAC'', ''SAS'', ''SEA'', ''TOR'', ''UTA'', ''VAN'',/ ''WAS'', ''WSB''] # Create the dictionary that defines the order for sorting sorterIndex = dict(zip(sorter,range(len(sorter)))) # Generate a rank column that will be used to sort # the dataframe numerically df[''Tm_Rank''] = df[''Tm''].map(sorterIndex) # Here is the result asked with the lexicographic sort # Result may be hard to analyze, so a second sorting is # proposed next ## NOTE: ## Newer versions of pandas use ''sort_value'' instead of ''sort'' df.sort([''Player'', ''Year'', ''Tm_Rank''], / ascending = [True, True, True], inplace = True) df.drop(''Tm_Rank'', 1, inplace = True) print(df) # Here is an example where ''Tm'' is sorted first, that will # give the first row of the DataFrame df to contain TOT as ''Tm'' df[''Tm_Rank''] = df[''Tm''].map(sorterIndex) ## NOTE: ## Newer versions of pandas use ''sort_value'' instead of ''sort'' df.sort([''Tm_Rank'', ''Player'', ''Year''], / ascending = [True , True, True], inplace = True) df.drop(''Tm_Rank'', 1, inplace = True) print(df)


Acabo de descubrir que con pandas 15.1 es posible usar series categóricas ( http://pandas.pydata.org/pandas-docs/stable/10min.html#categoricals )

En cuanto a su ejemplo, definamos el mismo cuadro de datos y clasificador:

import pandas as pd # Create DataFrame df = pd.DataFrame( {''id'':[2967, 5335, 13950, 6141, 6169],/ ''Player'': [''Cedric Hunter'', ''Maurice Baker'' ,/ ''Ratko Varda'' ,''Ryan Bowen'' ,''Adrian Caldwell''],/ ''Year'': [1991 ,2004 ,2001 ,2009 ,1997],/ ''Age'': [27 ,25 ,22 ,34 ,31],/ ''Tm'':[''CHH'' ,''VAN'' ,''TOT'' ,''OKC'' ,''DAL''],/ ''G'':[6 ,7 ,60 ,52 ,81]}) # Define the sorter sorter = [''TOT'', ''ATL'', ''BOS'', ''BRK'', ''CHA'', ''CHH'', ''CHI'', ''CLE'', ''DAL'',''DEN'',/ ''DET'', ''GSW'', ''HOU'', ''IND'', ''LAC'', ''LAL'', ''MEM'', ''MIA'', ''MIL'',/ ''MIN'', ''NJN'', ''NOH'', ''NOK'', ''NOP'', ''NYK'', ''OKC'', ''ORL'', ''PHI'',/ ''PHO'', ''POR'', ''SAC'', ''SAS'', ''SEA'', ''TOR'', ''UTA'', ''VAN'',/ ''WAS'', ''WSB'']

Con el marco de datos y el clasificador, que es un orden de categoría, podemos hacer lo siguiente en pandas 15.1:

# Convert Tm-column to category and in set the sorter as categories hierarchy # Youc could also do both lines in one just appending the cat.set_categories() df.Tm = df.Tm.astype("category") df.Tm.cat.set_categories(sorter, inplace=True) print(df.Tm) Out[48]: 0 CHH 1 VAN 2 TOT 3 OKC 4 DAL Name: Tm, dtype: category Categories (38, object): [TOT < ATL < BOS < BRK ... UTA < VAN < WAS < WSB] df.sort_values(["Tm"]) ## ''sort'' changed to ''sort_values'' Out[49]: Age G Player Tm Year id 2 22 60 Ratko Varda TOT 2001 13950 0 27 6 Cedric Hunter CHH 1991 2967 4 31 81 Adrian Caldwell DAL 1997 6169 3 34 52 Ryan Bowen OKC 2009 6141 1 25 7 Maurice Baker VAN 2004 5335