Подтвердить что ты не робот

Как можно сохранить порядок сохранения 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.

4b9b3361

Ответ 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')