修改作为参数传递的DataFrame

时间:2014-03-10 09:14:11

标签: python pandas

我有一个时间序列DataFrame(df),我需要添加一个列,然后将此df传递给修改单个列的时间片内容的函数。 我的想法如下:

rng = pd.date_range('1/1/2011', periods=3, freq='H')
df= pd.DataFrame([0,0,0],columns=['A'],index=rng)
df['B']=0

def v(dff,n):
    dff.loc[rng[0]:rng[1],:].B=n

据我所知,python参数传递,对v(df,n)的调用应该修改DataFrame,但问题是id不会一直这样做。

以下代码演示了此问题:

v(df,1)
print("Ater first: ", df)
v(df,2)
print("After second: ", df)

('Ater first: ',                      A  B
2011-01-01 00:00:00  0  0
2011-01-01 01:00:00  0  0
2011-01-01 02:00:00  0  0

[3 rows x 2 columns])
('After second: ',                      A  B
2011-01-01 00:00:00  0  2
2011-01-01 01:00:00  0  2
2011-01-01 02:00:00  0  0

这是令人惊讶的,因为我希望B列是以下0,0,0,或者是前1,1,0,然后是2,2,0。

如果我在第一次调用v之前放一个打印件(df),事情会变得更奇怪。代码:

print("Before: ", df)
v(df,1)
print("Ater first: ", df)
v(df,2)
print("After second: ", df)

Produces:
('Before: ',                      A  B
2011-01-01 00:00:00  0  0
2011-01-01 01:00:00  0  0
2011-01-01 02:00:00  0  0

[3 rows x 2 columns])
('Ater first: ',                      A  B
2011-01-01 00:00:00  0  1
2011-01-01 01:00:00  0  1
2011-01-01 02:00:00  0  0

[3 rows x 2 columns])
('After second: ',                      A  B
2011-01-01 00:00:00  0  2
2011-01-01 01:00:00  0  2
2011-01-01 02:00:00  0  0

所以结果取决于我是否打印了一个df ferore对调用它的函数的调用!

当且仅当我向df添加新列,获取时间范围切片然后修改该列时,才会发生这种情况。如果我首先创建一个包含2列的DataFrame,那么事情就会按预期工作。

发生了什么事?这是pandas或python中的错误还是我对python中的工作方式的理解是根本错误的?

由于

1 个答案:

答案 0 :(得分:1)

我认为你的问题与chain indexing有关,如果你改变你的功能,有时会有效:

def v(dff,n):
    dff.loc[rng[0]:rng[1],'B']=n

然后它按预期工作,这是推荐的分配语义,适用于所有情况。