2013-07-12 2 views
44

У меня есть следующий кадр данных:Как отсортировать кадр данных pandas, используя значения из нескольких столбцов?

df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 

Или в читабельной форме:

c1 c2 
0 3 10 
1 2 30 
2 1 20 
3 2 15 
4 2 100 

следующие сортировочно-команда работает, как ожидалось:

df.sort(['c1','c2'], ascending=False) 

Выход:

c1 c2 
0 3 10 
4 2 100 
1 2 30 
3 2 15 
2 1 20 

Но следующая команда:

df.sort(['c1','c2'], ascending=[False,True]) 

приводит

c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

и это не то, что я ожидал. Я ожидаю, что значения в первом столбце упорядочены от наибольшего к наименьшему, и если в первом столбце есть одинаковые значения, порядок по восходящим значениям из второго столбца.

Кто-нибудь знает, почему он не работает должным образом?

ДОБАВЛЕНО

Это копипаст:

>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 
+0

Какую версию панд и numpy вы используете? –

ответ

42

Ваш код работает для меня.

>>> import pandas 
>>> df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 
>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 

ли вы вставляете как?

>>> df.sort(['c1','c2'], ascending=[True,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

ОБНОВЛЕНИЕDataFrame.sort устарела; использование DataFrame.sort_values.

>>> df.sort(['c1','c2'], ascending=[False,True]) 
__main__:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
>>> df.sort_values(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
+0

Предложение: обратный порядок с оригиналом внизу, обновить вверх. Читая сверху вниз, я пробовал первый блок и задавался вопросом, почему это не удалось, будучи в двух словах запутанным, «он работает для меня» и «вы вставляете как есть» (конечно, это была моя ошибка!). Затем я прокрутил и увидел обновление ... – Hendy

2

Если вы пишете этот код в файле сценария, то вам придется писать так:

df = df.sort(['c1','c2'], ascending=[False,True]) 
21

Использование sort может привести предупреждающее сообщение. См. github обсуждение. Таким образом, вы могли бы хотеть использовать sort_values, документы here

Тогда ваш код может выглядеть следующим образом:

df = df.sort_values(by=['c1','c2'], ascending=[False,True]) 
+0

Я получаю предупреждение иначе '/Applications/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1: FutureWarning: sort (columns = ....) устарел, используйте sort_values ​​(by = .....) ' – abhiieor

+0

@patapouf_ai Нет,' sort' теперь устарел – oulenz

1

Я нашел, что это будет очень полезно:

df = pd.DataFrame({'A' : range(0,10) * 2, 'B' : np.random.randint(20,30,20)}) 

# A ascending, B descending 
df.sort(**skw(columns=['A','-B'])) 

# A descending, B ascending 
df.sort(**skw(columns=['-A','+B'])) 

Обратите внимание, что в отличие от стандарта columns=,ascending= аргументы, здесь имена столбцов и порядок их сортировки находятся на одном и том же месте. В результате ваш код становится намного легче читать и поддерживать.

Примечания фактического вызов .sort неизменен, skw (сек орта кВт арг) лишь небольшая вспомогательная функция, которая анализирует столбцы и возвращает обычные columns= и ascending= параметров для вас. Передайте ему любой другой вид kwargs, как обычно. Скопируйте/вставьте следующий код, например. ваш местный utils.py, тогда забудьте об этом и просто используйте его, как указано выше.

# utils.py (or anywhere else convenient to import) 
def skw(columns=None, **kwargs): 
    """ get sort kwargs by parsing sort order given in column name """ 
    # set default order as ascending (+) 
    sort_cols = ['+' + col if col[0] != '-' else col for col in columns] 
    # get sort kwargs 
    columns, ascending = zip(*[(col.replace('+', '').replace('-', ''), 
           False if col[0] == '-' else True) 
           for col in sort_cols]) 
    kwargs.update(dict(columns=list(columns), ascending=ascending)) 
    return kwargs 
+2

Это похоже на overkill по сравнению с другими параметрами. – digitaldavenyc

+0

только посмотрите на пример, а не на функцию 'sortkwargs'. это одноразовое определение, которое вы можете хранить и импортировать из своего, например. 'Util.py'. ваш код будет намного более гибким и удобочитаемым по сравнению с синтаксисом 'sort' по умолчанию. – miraculixx

+0

проголосовать за все, что вам нравится, пожалуйста, добавьте комментарий, чтобы я мог улучшить ответ – miraculixx

7

Метод dataframe.sort() - так что мое понимание - устарело в пандах> 0.18. Для того, чтобы решить вашу проблему, вы должны использовать dataframe.sort_values ​​() вместо:

f.sort_values(by=["c1","c2"], ascending=[False, True]) 

Выход выглядит следующим образом:

c1 c2 
    3 10 
    2 15 
    2 30 
    2 100 
    1 20 
4

В моем случае, принятый ответ не работает:

f.sort_values ​​(по = [ "c1", "c2"], восходящая = [Ложные, True])

только следующие работали, как и ожидалось:

f = f.sort_values(by=["c1","c2"], ascending=[False, True]) 
+2

Серьезно? В Pandas вы знаете что-то, что называется [inplace] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html) – Hng

Смежные вопросы