pandas: нет очевидного способа установить столбец для вывода функции применения в python 3.8 - PullRequest
0 голосов
/ 14 апреля 2020
def apply_inplace(df: DataFrame, columns: Union[str, List[str]], func: Callable):
    df.loc[:, columns] = df[columns].apply(func)  # why is this missing from pandas?

Это функция, которую я написал. Это совместимо со всеми возможными numpy массивами, которые я могу себе представить.

Это соответствует сообщению об ошибке, что порождает приведенный ниже синтаксически эквивалентный, но, по-видимому, функционально неэквивалентный пример:

df[columns] = df[columns].apply(func)

IE, который забивает артефакты выпуска Google и Github на протяжении python сообщество разработчиков:

C: \ ProgramData \ Anaconda3 \ lib \ site-packages \ pandas \ core \ indexing.py: 494: SettingWithCopyWarning:

Попытка значения для установки на копию среза из DataFrame.

Попробуйте вместо этого использовать .loc [row_indexer, col_indexer] = значение

См. предостережения в документации: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning -a-view-vers---a-copy

self.obj [item] = s

ТОЛЬКО ОДНА ОДНА ПРОБЛЕМА: СОБЛЮДЕНИЕ ЭТОЙ РЕКОМЕНДАЦИИ ВЫЗЫВАЕТ ТОЧНУЮ ЖЕ ОШИБКУ.

Я в замешательстве, потому что Pandas - это структура данных O(n*m), но у нас здесь есть микрооптимизация O (n), предоставляющая пользователю UNAVOIDABLE O ( n) реализованный с помощью интерпретируемого кода неявный артефакт оптимизации копирования, который не существует варианта использования, для которого достигается асимптотика c ускорения сложности во время выполнения при установке данных O(n*m).

Как же можно избежать этого чрезвычайно некомпетентного предупреждения?

Кроме, скажем, формирования нового фрейма данных и принудительной глубокой копии - ленивой или иной - всего O(n*m) набора данных только для обхода O(n) микроопции.


То, что я пробовал, не работает:

def apply_inplace(df: DataFrame, columns: Union[str, List[str]], func: Callable):
    df[columns] = numpy.asarray(df[columns].apply(func).values)

def apply_inplace(df: DataFrame, columns: Union[str, List[str]], func: Callable):
    df[columns] = deepcopy(numpy.asarray(df[columns].apply(func).values))

def apply_inplace(df: DataFrame, columns: Union[str, List[str]], func: Callable):
    df.loc[:,columns] = deepcopy(asarray(df[columns].apply(func).values))

То, что я пробовал, что работает , на повторной основе. Примечание: я должен явно принудительно вызвать глубокую O(n*m) копию:

def apply(df: DataFrame, columns: Union[str, List[str]], func: Callable, axis: int = 0) -> DataFrame:
    df2 = deepcopy(df)

    vfunc = np.vectorize(func) # at some point, this "became" necessary.
    df2[columns] = df[columns].apply(vfunc,axis)
    return df2

В качестве альтернативы, я мог бы написать около 10-30 строк кода, где я тщательно восстанавливаю фреймы данных и объединяю их вместе точно так, как они мы. Не желательное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...