我的情景是,一个函数应该能够修改pandas.DataFrame
中的值。但我不想将整个DataFrame暴露给函数,只是需要修改的部分。这种透明度的一个原因是,该功能将更具有通用性,能够指定从外部修改DataFrame的哪一部分。成像我可以编写一个函数mult(df_view, a)
,将视图中的所有值乘以a
。请注意,我不希望创建新的DataFrame。价值变化应该是就地。Python Pandas:如何将DataFrames的“视图”传递给函数?
这是我的尝试:
df = pd.DataFrame([[1,1],[1,1]])
def mult(df_view, a):
df_view *= a
mult(df.loc[1,1], 2)
print(df)
这是(不需要)输出:
0 1
0 1 1
1 1 1
预期输出是:
0 1
0 1 1
1 1 2
注意到,如果我们做的分配直接(即没有功能),它的工作原理:
df = pd.DataFrame([[1,1],[1,1]])
df.loc[1,1] *= 2
print(df)
...给:
0 1
0 1 1
1 1 2
因此,通过该视图通过函数调用时,显然我搞乱了的东西。我读过这个blog post from Jeff Knupp,我想我明白python的名称 - 对象绑定是如何工作的。我对DataFrames的理解是,当我呼叫df.loc[1,1]
时,它会生成一个代理对象,该对象指向原始DataFrame w/[1,1]
窗口,以便进一步的操作(例如分配)只转到窗口内的元素。现在,当我通过函数调用传递df.loc[1,1]
时,该函数将名称df_view
绑定到代理对象。因此,在我的理论中,任何变化(即df_view *= a
)都应该应用于视图,并因此应用于原始DataFrame中的元素。从结果中,很明显这没有发生,看起来DataFrame在进程中被复制(我不确定在哪里),因为一些值在原始DataFrame之外被更改了。
是'numpy.int64'并不意味着在数据帧中值的数据不能被分配至。实际上它在'df.loc [1,1] * = 2'的情况下。正如你所指出的那样,何时/为什么传递一个“视图”到'mult()'函数的逻辑会有点不清楚。这不是一个明确的答案(尽管你指出了一些成功的和失败的案例有帮助)。 – Roy
@Roy Python通过赋值传递,当你直接使用'df.loc [1,1] * = 2'时,你仍然分配给DataFrame的_element_,而不是传递给函数的实际值。 [这是一个很好的阅读](http://nedbatchelder.com/text/names.html)。 – miradulo