Pandas split-apply-Объединить, почему объединение с pd.concat ([df]) работает при сортировке? - PullRequest
0 голосов
/ 30 апреля 2018

Я делаю рабочий процесс типа split-apply-merge с пандами. Часть 'apply' возвращает DataFrame. Когда DataFrame, который я запускаю gropupby, сначала сортируется, просто возвращая DataFrame из apply поднимает ValueError: cannot reindex from a duplicate axis. Вместо этого я обнаружил, что он работает правильно, когда я возвращаю pd.concat([df]) (вместо просто return df). Если я не сортирую DataFrame, оба способа объединения результатов будут работать правильно. Я ожидаю, что сортировка должна что-то делать с индексом, но я не понимаю, что. Может кто-нибудь объяснить, пожалуйста?

import pandas as pd
import numpy as np


def fill_out_ids(df, filling_function, sort=False, sort_col='sort_col',
                 group_by='group_col', to_fill=['id1', 'id2']):

    df = df.copy()
    df.set_index(group_by, inplace=True)
    if sort:
        df.sort_values(by=sort_col, inplace=True)
    g = df.groupby(df.index, sort=False, group_keys=False)
    df = g.apply(filling_function, to_fill)
    df.reset_index(inplace=True)
    return df


def _fill_ids_concat(df, to_fill):
    df[to_fill] = df[to_fill].fillna(method='ffill')
    df[to_fill] = df[to_fill].fillna(method='bfill')
    return pd.concat([df])


def _fill_ids_plain(df, to_fill):
    df[to_fill] = df[to_fill].fillna(method='ffill')
    df[to_fill] = df[to_fill].fillna(method='bfill')
    return df


def test_fill_out_ids():
    input_df = pd.DataFrame(
        [
            ['a',       None,       1.0,    1],
            ['a',       None,       1.0,    3],
            ['a',       'name1',    np.nan, 2],

            ['b',       None,       2.0,    3],
            ['b',       'name1',    np.nan, 2],
            ['b',       'name2',    np.nan, 1],
        ],
        columns=['group_col', 'id1', 'id2', 'sort_col']
    )

    # this works
    fill_out_ids(input_df, _fill_ids_plain, sort=False)

    # this raises: ValueError: cannot reindex from a duplicate axis
    fill_out_ids(input_df, _fill_ids_plain, sort=True)

    # this works
    fill_out_ids(input_df, _fill_ids_concat, sort=True)

    # this works
    fill_out_ids(input_df, _fill_ids_concat, sort=False)


if __name__ == "__main__":
    test_fill_out_ids()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...