TL;DR:使用.loc[:, 'foo']而不是.foo
pandas 什么时候给视图赋值,什么时候给副本赋值?
AFAIK,pandas 要么返回视图,要么返回副本,具体取决于您使用的方法。
如果为视图分配值,则可以更改原始数据框,但如果为副本分配值,则无法更改原始数据框。
然而,下面的行为让我感到困惑。为什么为视图分配值适用于数据框而不适用于系列?
dd = pd.DataFrame([
{'a': 1, 'b': 2},
{'a': 2, 'b': 4},
{'a': 4, 'b': 3},
])
dd[dd.a == 1] = pd.DataFrame([{'a': 100, 'b': 200}]) # Assigning value works.
dd
>> a b
0 100 200
1 2 4
2 4 3
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,第一行的值已更改。
但是,如下所示,为系列分配值不起作用,即使设置相同(除了我称为系列之外)。
dd = pd.DataFrame([
{'a': 1, 'b': 2},
{'a': 2, 'b': 4},
{'a': 4, 'b': 3},
])
dd[dd.a == 1].a = 1000 # Assigning value doesn't work.
dd
>> a b
0 1 2
1 2 4
2 4 3
Run Code Online (Sandbox Code Playgroud)
不过我在 pandas 0.19.1 上。(因为我使用的是Python 2.7)
太长了;
我想你自己已经回答了你的问题。为视图分配值的行为方式与您期望的方式相同,而为副本分配值不会修改原始数据框。
在本质上;
dd[dd.a == 1].a是数据帧切片中值的副本dd.a[dd.a == 1]是同一数据帧的另一个切片 (df.a) 的切片(按条件)的视图。以下是数据帧的条件切片dd,因此它是数据帧的视图。同样,带有 的loc,这是推荐的方式。
dd[dd.a == 1] #Slice of a dataframe based on condition returned as a view
dd.loc[dd.a == 1] #Slice of a dataframe based on condition returned as a view
Run Code Online (Sandbox Code Playgroud)
当您从此切片中提取特定列时,您最终会得到一个副本 -
dd[dd.a == 1].a = 100
#This syntax basically says -
#From the view of a slice of dd, give me values of 'a' and set that to 100"
#The assignment here is that to a copy and not to a view
Run Code Online (Sandbox Code Playgroud)
a b
0 1 2
1 2 4
2 4 3
Run Code Online (Sandbox Code Playgroud)
因此分配不会对原始数据帧产生影响。
如果您想为特定列进行分配,那么您需要这样做 -
dd.a[dd.a == 1] = 100
#This syntax basically says -
#"From the slice, dd.a give me aother slice based on condition and set that slice to 100"
#The assignment happens a sliced view of the dataframe itself
Run Code Online (Sandbox Code Playgroud)
a b
0 100 2
1 2 4
2 4 3
Run Code Online (Sandbox Code Playgroud)
希望这能回答你的问题。