考虑数据框df
df = pd.DataFrame(dict(A=[1, 2, 3]))
df
A
0 1
1 2
2 3
现在我将分配给变量a
系列df.A
a = df.A
a
0 1
1 2
2 3
Name: A, dtype: int64
我现在会增加a
的索引
a.index = a.index + 1
print(a)
print()
print(df)
1 1
2 2
3 3
Name: A, dtype: int64
A
0 1
1 2
2 3
这里没什么可看的。一切如预期......
但现在我要重新分配a = df.A
a = df.A
print(a)
print()
print(df)
1 1
2 2
3 3
Name: A, dtype: int64
A
0 1
1 2
2 3
我刚从a
直接重新分配df
。 df
索引就是这样,但a
索引不同。它是在我增加它之后和我重新分配之前的原因。
当然,如果我重新构建df
,一切都会重置。
df = pd.DataFrame(dict(A=[1, 2, 3]))
a = df.A
print(a)
print()
print(df)
0 1
1 2
2 3
Name: A, dtype: int64
A
0 1
1 2
2 3
但这必须意味着pd.Series
对象中正在跟踪的pd.DataFrame
对象会跟踪它自己的索引,而该索引在{{{ 1}}级别。
问题
我能正确地解释这个吗?
它甚至会导致这样的怪异:
pd.DataFrame
答案 0 :(得分:4)
这看起来像是python对象标识的错误或意外后果,在赋值之前我们可以看到索引是相同的:
In [175]:
df = pd.DataFrame(dict(A=[1, 2, 3]))
df
Out[175]:
A
0 1
1 2
2 3
In [176]:
print(id(df.index))
print(id(df['A']))
print(id(df['A'].index))
a = df.A
a
132848496
135123240
132848496
Out[176]:
0 1
1 2
2 3
Name: A, dtype: int64
现在,如果我们修改引用,索引现在变成了不同的对象,a
和df['A']
都是相同的:
In [177]:
a.index = a.index + 1
print(a)
print(id(a))
print(id(df.A))
print()
print(df)
print(id(df.A.index))
print(id(a.index))
1 1
2 2
3 3
Name: A, dtype: int64
135123240
135123240
A
0 1
1 2
2 3
135125144
135125144
但现在df.index
与df['A'].index
和a.index
不同:
In [181]:
print(id(df.index))
print(id(a.index))
print(id(df['A'].index))
132848496
135124808
135124808
就我个人而言,我认为这是一个意想不到的后果,因为一旦你将a
引用到'A'
列,一旦你开始改变引用和我敢打赌,这比通常的df
警告
为了避免这种情况,最好调用Setting on copy
进行深层复制,以便任何突变都不会影响原始数据:
copy()
答案 1 :(得分:1)
它是引用游戏(指针),每个DataFrame都有自己的索引数组,DataFrame中的系列引用了相同的索引数组
执行a.index = a.index + 1
时,系列中的引用已更改,因此a.index与df.A.index相同,不同于df.index
现在,如果您尝试清除df缓存,则会重置系列:
print(df.A.index)
df._clear_item_cache()
print(df.A.index)
默认情况下,DataFrame中的系列索引是不可变的,但复制系列引用允许一种变通方法来编辑索引引用