functools уменьшает In-Place, изменяет исходный фрейм данных

В настоящее время я сталкиваюсь с проблемой, что «functools.reduce (operator.iadd, ...)» изменяет исходный ввод. Например

У меня есть простой dataframe df = pd.DataFrame ([[[A ',' B ']], [[' C ',' D ']]])

        0
0  [A, B]
1  [C, D]

Применение оператора iadd приводит к следующему результату:

functools.reduce(operator.iadd, df[0])
['A', 'B', 'C', 'D']

Теперь исходный df изменился на

              0
0  [A, B, C, D]
1        [C, D]

Также копирование df с использованием df.copy (deep = True) заранее не помогает.

У кого-нибудь есть идея преодолеть эту проблему? THX, Lazloo

Всего 2 ответа


Используйте operator.add вместо operator.iadd :

In [8]: functools.reduce(operator.add, df[0])
Out[8]: ['A', 'B', 'C', 'D']

In [9]: df
Out[9]: 
        0
0  [A, B]
1  [C, D]

В конце концов, operator.iadd(a, b) совпадает с a += b . Поэтому он изменяет df[0] . Напротив, operator.add(a, b) возвращает a + b , поэтому нет никакой модификации df[0] .


Или вы можете вычислить одну и ту же величину, используя df[0].sum() :

In [39]: df[0].sum()
Out[39]: ['A', 'B', 'C', 'D']

Документы для df.copy предупреждают:

Когда deep=True , данные копируются, но фактические объекты Python не будут скопированы рекурсивно , а только ссылка на объект.

Поскольку df[0] содержит списки Python, списки не копируются даже с df.copy(deep=True) . Вот почему изменение копии по-прежнему влияет на df .


В дополнение к хорошему ответу @ unutbu вы также можете использовать метод int.__add__ :

df = pd.DataFrame([[['A', 'B']], [['C', 'D']]])
functools.reduce(lambda x,y: (x).__add__(y), df[0])
print(df)

И вы можете видеть, что это:

        0
0  [A, B]
1  [C, D]

Для вывода !!!


Есть идеи?

10000