functools reduce In-Place修改原始数据框

时间:2018-11-05 06:46:49

标签: python python-3.x pandas dataframe functools

我目前面临“ functools.reduce(operator.iadd,...)”更改原始输入的问题。例如

我有一个简单的数据框     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.copy(deep = True)复制df并没有帮助。

有人想克服这个问题吗? THX,Lazloo

2 个答案:

答案 0 :(得分:3)

使用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']

docs for df.copy警告:

  

deep=True时,数据被复制,但实际的Python对象   不会递归复制,而只会复制对对象的引用。

由于df[0]包含Python列表,因此即使使用df.copy(deep=True)也不会复制这些列表。这就是为什么修改副本仍会影响df的原因。

答案 1 :(得分:0)

除了@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]

用于输出!