Python Pandas:如何通过"观看"将DataFrame转换为函数?

时间:2017-02-21 15:13:44

标签: python python-3.x pandas dataframe

我的方案是函数应该能够修改pandas.DataFrame内的值。但我不想将整个DataFrame暴露给函数,只需要修改需要修改的部分。这种透明性的一个原因是该函数将更加通用,能够指定从外部修改DataFrame的哪个部分。成像我可以编写一个函数mult(df_view, a),它将视图中的所有值乘以a。请注意,我不想创建新的DataFrame。值更改应就地

这是我的尝试:

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]时,它会生成一个代理对象,该对象指向具有[1,1]窗口的原始DataFrame,以便进一步的操作(例如赋值)仅转到窗口内的元素。现在,当我通过函数调用传递df.loc[1,1]时,该函数将名称df_view绑定到代理对象。因此,在我的理论中,任何更改(即df_view *= a)都应该应用于视图,从而应用于原始DataFrame中的元素。从结果来看,显然没有发生,似乎DataFrame在过程中被复制(我不知道在哪里),因为某些值在原始DataFrame之外被更改。

2 个答案:

答案 0 :(得分:0)

请检查

>>> type(df.loc[1, 1])
numpy.int64

显然这不会起作用 - 你传入一个不可变的int,它没有绑定到外部DataFrame。

如果您使用简单的索引(可变构造)传递实际视图,它很可能工作。

>>> mult(df.loc[:, 1], 2)
>>> df
    0  1
0   1  2
1   1  2

但是其他一些操作不起作用。

>>> mult(df.loc[:, :1], 2)
>>> df
    0  1
0   1  2
1   1  2

总而言之,我认为这种控制流程是一个坏主意 - 更好的选择是在你展示作品时直接在索引上操作。当你在可能的情况下坚持不变性时,熊猫往往更友好(恕我直言)。

答案 1 :(得分:0)

在某些情况下,有时会difficult to detect出现数据副本的问题。

您可以通过索引函数来解决难题:

def mult(df,i,j,a):
    df.loc[i,j]*=a

mult(df,1,1,2)
mult(df,1,slice(0,2),6)
print(df)

   0  1
0  1  1
1  6 12