Сортировка по нескольким столбцам в Pandas, но с 'na_position' для вторичной сортировки - PullRequest
2 голосов
/ 03 августа 2020

У меня есть Pandas DataFrame вроде этого

df = pd.DataFrame(
 {
   'OrderID': ['o1','o2','o3','o4','o5'],
   'CustomerID': ['c1','c1','c2','c2','c3'],
   'CustomerRating': [5,1,3, NaN,NaN]
    
 }
)

Я хочу отсортировать его сначала по CustomerID, а затем по CustomerRating и таким образом, чтобы NaN в рейтинге клиентов были последними. Я знаю о df.sort_values(na_position = 'last'), но это работает только для первичной сортировки. Как мне заставить его работать для вторичной сортировки?

Так же, как я указываю восходящий аргумент в виде списка, где каждый элемент соответствует одному уровню сортировки, мне нужно что-то подобное для аргумента na_position, поэтому что-то вроде этого:

df.sort_values(['CustomerID', 'CustomerRating', ascending = [False, False], na_position =['last', 'last']]

Как мне это сделать?

Спасибо

Ответы [ 3 ]

0 голосов
/ 03 августа 2020

Следующий код упорядочивает строки на основе количества нулевых значений, присутствующих в каждой строке.

df.iloc[df.isnull().sum(axis=1).mul(1).argsort()]

Альтернативное решение

Приведенный ниже код будет работать идеально подходит для всех тестовых случаев. Нулевые значения всегда будут присутствовать в последнем и одновременно упорядоченном по OrderID и CustomerID.

null_df=df[df.isnull().any(axis=1)]
all_df=df[~df.index.isin(null_df.index)]

all_df.sort_values(['OrderID', 'CustomerID'], ascending = [True, True], inplace=True)
null_df.sort_values(['OrderID', 'CustomerID'], ascending = [True, True], inplace=True)

final_df=pd.concat([all_df, null_df]).reset_index(drop=True)
0 голосов
/ 03 августа 2020

простой df.sort_values ​​(['CustomerID', 'CustomerRating'])

0 голосов
/ 03 августа 2020

Из документации надо Specify list for multiple sort orders. Моя интерпретация, порядок сортировки должен быть логичным. Кроме того, вы не можете указать, что na_position соответствует столбцу без NaN.

 print(df.sort_values(['CustomerID', 'CustomerRating'], ascending = [False, False], na_position ='first'))#Here, NaN is first because `c3` and `c2` appear on top



  OrderID CustomerID  CustomerRating
4      o5         c3             NaN
3      o4         c2             NaN
2      o3         c2             3.0
0      o1         c1             5.0
1      o2         c1             1.0

print(df.sort_values(['CustomerID', 'CustomerRating'], ascending = [True, True], na_position ='last'))# This is reversed again because the sort is logical



   OrderID CustomerID  CustomerRating
1      o2         c1             1.0
0      o1         c1             5.0
2      o3         c2             3.0
3      o4         c2             NaN
4      o5         c3             NaN

print(df.sort_values(['CustomerID', 'CustomerRating'], ascending = [False, True], na_position ='first'))



  OrderID CustomerID  CustomerRating
4      o5         c3             NaN
3      o4         c2             NaN
2      o3         c2             3.0
1      o2         c1             1.0
0      o1         c1             5.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...