我使用的是Python 3.6和Pandas 0.20.3。
我确定必须在某处解决,但我似乎无法找到它。我通过添加列来改变函数内的数据帧;然后我将数据帧恢复到原始列。我没有退回数据帧。添加的列保持不变。 我可以理解,如果我在函数内添加列,它们不是永久性的,更新数据帧不起作用。我还了解添加列是否会改变数据帧并且分配数据帧也会卡住。 这是代码:
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]
然后运行它并显示dataframe:
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]
我猜测如果我返回新的数据帧,那么将会有一个可能需要通过垃圾收集处理的大型数据帧。
答案 0 :(得分:1)
要了解会发生什么,您应该知道按值传递属性与通过引用传递属性之间的区别:
您将变量df
传递给函数messing_around
。该函数通过添加列来就地修改原始数据框。
这个后续的代码行似乎是引起混淆的原因:
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