了解Python中的变量范围和更改
我正在使用Python 3.6和Pandas 0.20.3 我肯定这一定是在什么地方写的,但我似乎找不到。我通过添加列来改变函数中的数据帧;然后我将dataframe恢复到原始列。我不返回数据帧。添加的列保持不变。 我可以理解,如果我在函数中添加列,它们不是永久性的,并且更新数据帧不起作用。我还可以理解,添加列是否改变了数据帧,分配数据帧是否也卡住了。 代码如下:了解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
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
这是一个很好的建议,但在这种情况下,数据并不重要