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 строк кода, где я тщательно восстанавливаю фреймы данных и объединяю их вместе точно так, как они мы. Не желательное решение.