我有一个时间序列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中的工作方式的理解是根本错误的?
由于
答案 0 :(得分:1)
我认为你的问题与chain indexing
有关,如果你改变你的功能,有时会有效:
def v(dff,n):
dff.loc[rng[0]:rng[1],'B']=n
然后它按预期工作,这是推荐的分配语义,适用于所有情况。