Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解Python中的变量范围和更改_Python_Function_Pandas - Fatal编程技术网

了解Python中的变量范围和更改

了解Python中的变量范围和更改,python,function,pandas,Python,Function,Pandas,我正在使用Python 3.6和Pandas 0.20.3 我肯定这一定是在什么地方写的,但我似乎找不到。我通过添加列来改变函数中的数据帧;然后我将dataframe恢复到原始列。我不返回数据帧。添加的列保持不变。 我可以理解,如果我在函数中添加列,它们不是永久性的,并且更新数据帧不起作用。我还可以理解,添加列是否改变了数据帧,分配数据帧是否也卡住了。 代码如下: import numpy as np import pandas as pd df = pd.DataFrame(np.random

我正在使用Python 3.6和Pandas 0.20.3

我肯定这一定是在什么地方写的,但我似乎找不到。我通过添加列来改变函数中的数据帧;然后我将dataframe恢复到原始列。我不返回数据帧。添加的列保持不变。 我可以理解,如果我在函数中添加列,它们不是永久性的,并且更新数据帧不起作用。我还可以理解,添加列是否改变了数据帧,分配数据帧是否也卡住了。 代码如下:

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(10, 5))
df

    0               1           2             3       4
0   0.406779    -0.481733   -1.187696   -0.210456   -0.608194
1   0.732978    -0.079787   -0.051720   1.097441    0.089850
2   1.859737    -1.422845   -1.148805   0.254504    1.207134
3   0.074400    -1.352875   -1.341630   -1.371050   0.005505
4   -0.102024   -0.905506   -0.165681   2.424180    0.761963
5   0.400507    -0.069214   0.228971    -0.079805   -1.059972
6   1.284812    0.843705    -0.885566   1.087703    -1.006714
7   0.135243    0.055807    -1.217794   0.018104    -1.571214
8   -0.524320   -0.201561   1.535369    -0.840925   0.215584
9   -0.495721   0.284237    0.235668    -1.412262   -0.002418
现在,我创建一个函数:

def mess_around(df):
    cols = df.columns
    df['extra']='hi'
    df = df[cols]
然后运行它并显示数据帧:

mess_around(df)
df
其中:

        0         1             2           3          4       extra
0   0.406779    -0.481733   -1.187696   -0.210456   -0.608194   hi
1   0.732978    -0.079787   -0.051720   1.097441    0.089850    hi
2   1.859737    -1.422845   -1.148805   0.254504    1.207134    hi
3   0.074400    -1.352875   -1.341630   -1.371050   0.005505    hi
4   -0.102024   -0.905506   -0.165681   2.424180    0.761963    hi
5   0.400507    -0.069214   0.228971    -0.079805   -1.059972   hi
6   1.284812    0.843705    -0.885566   1.087703    -1.006714   hi
7   0.135243    0.055807    -1.217794   0.018104    -1.571214   hi
8   -0.524320   -0.201561   1.535369    -0.840925   0.215584    hi
9   -0.495721   0.284237    0.235668    -1.412262   -0.002418   hi
我知道我可以通过返回ts来解决问题。因此我可以修复问题。我想知道我错在哪里。我怀疑变量ts的范围在函数内部;它被赋予一个指针,但该指针不会因为作用域而改变。然而,列分配使用传入的指针,因此“直接”影响数据帧。对吗

编辑: 对于那些可能希望就地处理数据帧的人,我添加了:

for c in ts.columns:
    if c not in cols:
        del ts[c]

我猜如果我返回新的数据帧,那么将有一个潜在的大数据帧,必须通过垃圾收集来处理。

要了解发生了什么,您应该知道按值向函数传递属性与按引用传递属性之间的区别:


将变量
df
传递给函数
messing\u
。该函数通过添加列来修改原始数据帧

下面这行代码似乎是造成混淆的原因:

df = df[cols]
这里发生的是变量
df
最初包含对数据帧的引用。但是,重新分配会导致变量指向不同的对象-您的原始数据帧不会更改

下面是一个简单的例子:

def foo(l):
    l.insert(0, np.nan)   # original modified
    l = [4, 5, 6]         # reassignment - no change to the original, 
                          # but the variable l points to something different

lst = [1, 2, 3]    
foo(lst)

print(lst)
[nan, 1, 2, 3]            # notice here that the insert modifies the original,
                          # but not the reassignment

这是一个很好的建议,但在这种情况下,数据并不重要