理解Python

时间:2017-10-02 20:25:04

标签: python function pandas

我使用的是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]

我猜测如果我返回新的数据帧,那么将会有一个可能需要通过垃圾收集处理的大型数据帧。

1 个答案:

答案 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