【问题标题】:Passing pandas DataFrame by reference通过引用传递 pandas DataFrame
【发布时间】:2017-02-08 13:30:15
【问题描述】:

我的问题是关于 pandas DataFrame 在通过引用传递时的不变性。考虑以下代码:

import pandas as pd

def foo(df1, df2):

    df1['B'] = 1
    df1 = df1.join(df2['C'], how='inner')

    return()

def main(argv = None):

    # Create DataFrames. 
    df1 = pd.DataFrame(range(0,10,2), columns=['A'])
    df2 = pd.DataFrame(range(1,11,2), columns=['C'])

    foo(df1, df2)    # Pass df1 and df2 by reference.

    print df1

    return(0)

if __name__ == '__main__':
    status = main()
    sys.exit(status)

输出是

   A  B  
0  0  1
1  2  1
2  4  1
3  6  1
4  8  1

而不是

   A  B  C
0  0  1  1
1  2  1  3
2  4  1  5
3  6  1  7
4  8  1  9

其实如果foo被定义为

def foo(df1, df2):

    df1 = df1.join(df2['C'], how='inner')
    df1['B'] = 1

    return()

(即另一个语句之前的“join”语句)那么输出就是

   A    
0  0 
1  2 
2  4 
3  6 
4  8

我很好奇为什么会这样。任何见解将不胜感激。

【问题讨论】:

  • 顺便说一句,return 不是函数,它只是一个语句,所以你不需要它后面的括号。
  • This 是我所知道的关于 Python 名称如何工作的最佳讨论。一旦你理解了这一点,你就会理解这种行为。
  • 感谢@chthonicdaemon!

标签: python pandas dataframe pass-by-reference immutability


【解决方案1】:

问题是因为这行:

df1 = df1.join(df2['C'], how='inner')

df1.join(df2['C'], how='inner') 返回一个新的数据框。在这一行之后,df1 不再引用与参数相同的数据帧,而是一个新数据帧,因为它已被重新分配给新结果。第一个数据帧继续存在,未修改。这不是真正的 pandas 问题,只是 python 和大多数其他语言的一般工作方式。

一些 pandas 函数有一个 inplace 参数,它可以做你想做的事,但是 join 操作没有。如果您需要修改数据框,则必须返回这个新数据框并在函数外部重新分配它。

【讨论】:

  • 谢谢@Jezzamon。这是有道理的。
【解决方案2】:

Python 没有按值传递与按引用传递——只有bindings from names to objects

如果您将功能更改为

def foo(df1, df2):

    res = df1.join(df2['C'], how='inner')
    res['B'] = 1

    return res

然后df1df2,在函数中,绑定到你发送的对象。 join 的结果,在这种情况下是一个新对象,绑定到名称 res。您可以操作它并返回它,而不会影响任何其他对象或绑定。

在你的调用代码中,你可以写

print foo(df1, df2)

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2013-09-10
    • 2020-04-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    相关资源
    最近更新 更多