`значения сортировки » с «ключом» работают не так, как ожидалось

#python #pandas

Вопрос:

 names = ['2', '0', '1']
values = [2, 0, 1]
dc = dict(names=names, values=values)
df = pd.DataFrame(dc, columns=list(dc))

key_fn = lambda s: pd.Series(sorted(s, key=lambda name: int(name)))
print(df.sort_values(['names'], key=key_fn))
 

доходность

   names  values
0     2       2
1     0       0
2     1       1
 

Тем не менее, сортировка правильная, что мы можем подтвердить с помощью

 kfn = lambda s: print(key_fn(s)) or key_fn(s)
df.sort_values(['names'], key=kfn)
 
 0    0
1    1
2    2
dtype: object
 

key_fn согласен с документами

ключевая функция должна быть векторизована. Он должен ожидать серию и возвращать серию с той же формой, что и входные данные.

Почему это не работает? Я не ищу обходной путь к этому простому примеру, мне нужно уметь использовать общее key . Windows 10, панды 1.3.3, Python 3.8.12.

Комментарии:

1. key Аргумент используется для указания Ряда значений, которые сортируются вместо фактических значений в столбце. Вместо этого вы предоставили уже отсортированную коллекцию значений.

2. Я действительно не понимаю вопроса. key это просто какая-то функция, которая манипулирует значениями так, чтобы для сортировки использовались эти производные значения, а не исходные значения. Т. Е. если вы хотите сортировать на основе абсолютного значения, вы бы key = lambda s: s.abs() это сделали . Это в основном просто избавляет вас от создания промежуточного столбца, сортировки по нему, а затем удаления этого промежуточного столбца.

3. @HenryEcker Документы неоднозначны в этом отношении, но вы ответили на мой вопрос. У меня есть рабочий код, но не стесняйтесь публиковать ответ.

Ответ №1:

Ваша ключевая функция уже отсортирована, так что сортировать (осталось) нечего. Попробуй:

 key_fn = lambda s: s.astype('int')
 

или:

 key_fn = lambda s: pd.Series([int(x) for x in s])
 

Комментарии:

1. Как указано, я стремлюсь использовать общее key . Это не сработает, если names = ['r0', 'r1', 'r2'] и не объясняет, почему мой код не работает.

2. Это совершенно другой вопрос. Те ключи терпят неудачу, о int(name) которых вы не спрашивали в этом вопросе. Так что даже sorted(s, key=lambda name: int(name) это не работает. И это не имеет отношения к key аргументу в Pandas.DataFrame.sort_values() .