Как можно сохранить порядок сохранения pandas?
У меня есть два DataFrames в pandas, пытаясь их объединить. Но pandas продолжает изменять порядок. Я попытался установить индексы, сбросив их, независимо от того, что я делаю, я не могу получить возвращаемый вывод, чтобы строки были в том же порядке. Есть трюк? Обратите внимание, что мы начинаем с заказа на кредиты "a, b, c", но после слияния это "a, c, b".
import pandas
loans = [ 'a', 'b', 'c' ]
states = [ 'OR', 'CA', 'OR' ]
x = pandas.DataFrame({ 'loan' : loans, 'state' : states })
y = pandas.DataFrame({ 'state' : [ 'CA', 'OR' ], 'value' : [ 1, 2]})
z = x.merge(y, how='left', on='state')
Но теперь порядок больше не является оригинальным "a, b, c". Есть идеи? Я использую pandas версию 11.
Ответы
Ответ 1
Надеюсь, кто-то предоставит лучший ответ, но в случае, если никто этого не сделает, это определенно будет работать, поэтому...
Zeroth, я предполагаю, что вы не хотите просто сортировать по loan
, но сохранить любой первоначальный порядок в x
, что может иметь или не иметь ничего общего с порядком loan
. (В противном случае проблема проще и менее интересна.)
Сначала вы просите его сортировать на основе ключей соединения. Поскольку документы объясняют, что по умолчанию, когда вы не передаете аргумент sort
.
Во-вторых, если вы не сортируете на основе ключей соединения, строки будут группироваться вместе, так что две строки, которые сливаются из одной и той же строки источника, оказываются рядом друг с другом, что означает, что вы все еще собираетесь для получения a
, c
, b
.
Вы можете обойти это, получив ряды, сгруппированные вместе, в порядке их появления в исходном x
, просто слияв снова с x
(с обеих сторон это не имеет особого значения) или путем переиндексации на основе на x
, если хотите. Вот так:
x.merge(x.merge(y, how='left', on='state', sort=False))
В качестве альтернативы вы можете вставить x-index там с reset_index
, а затем просто отсортировать его, например:
x.reset_index().merge(y, how='left', on='state', sort=False).sort('index')
В любом случае, очевидно, кажется немного расточительным и неуклюжим... так что, как я сказал, надеюсь, есть лучший ответ, который я сейчас не вижу. Но если нет, это работает.
Ответ 2
Самый быстрый способ, которым я нашел слияние и восстановление порядка - если вы объединяете "левый" - это включить исходный порядок в качестве столбца в левом фрейме данных перед слиянием, а затем использовать его для восстановления порядка после слияния:
import pandas
loans = [ 'a', 'b', 'c' ]
states = [ 'OR', 'CA', 'OR' ]
x = pandas.DataFrame({ 'loan' : loans, 'state' : states })
y = pandas.DataFrame({ 'state' : [ 'CA', 'OR' ], 'value' : [ 1, 2]})
import numpy as np
x["Order"] = np.arange(len(x))
z = x.merge(y, how='left', on='state').set_index("Order").ix[np.arange(len(x)), :]
Этот метод быстрее, чем сортировка. Здесь это как функция:
def mergeLeftInOrder(x, y, on=None):
x = x.copy()
x["Order"] = np.arange(len(x))
z = x.merge(y, how='left', on=on).set_index("Order").ix[np.arange(len(x)), :]
return z
Ответ 3
Pandas v0.8.0 введена новая функция слияния, которая учитывает порядок - ordered_merge
, поэтому ваше решение теперь так же просто, как:
z = pandas.ordered_merge(x, y, on='state')