yse*_*rka 7 python indexing pandas
我有一个如下数据框:
df = pd.DataFrame([[1,2],[10,20],[10,2],[1,40]],columns = ['a','b'])
a b
0 1 2
1 10 20
2 10 2
3 1 40
Run Code Online (Sandbox Code Playgroud)
我想选择b列在哪里a == 1,以下是经典选择:
df[df.a == 1].b
a b
0 1 2
3 1 40
Run Code Online (Sandbox Code Playgroud)
然后我想选择这个子数据帧的第i行,这不是索引为i的行.还有几种方法,如下所示:
df[df.a == 1].b.iloc[[1]]
Output:
3 40
Name: b, dtype: int64
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.问题是当我尝试修改我到达那里的值时,实际上这个选择方法会产生数据帧切片的副本,而不是对象本身.因此我无法在原地进行修改.
test[test.a == 1].b.iloc[[1]] = 3
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
Run Code Online (Sandbox Code Playgroud)
我不知道"复制"问题在哪个部分,因为以下两个产生同样的问题:
test.iloc[[3]].b = 3
test[test.a == 1].b = 3
Run Code Online (Sandbox Code Playgroud)
所以我的问题是这样的:如何通过掩码选择(有条件地在a列值上)和行选择(通过子数据帧中的行的排名,而不是其索引值)来更改值?
loc与布尔掩码一起使用,并直接向上传递索引:
In[178]:
df.loc[df.loc[df['a'] == 1,'b'].index[1], 'b'] = 3
df
Out[178]:
a b
0 1 2
1 10 20
2 10 2
3 1 3
Run Code Online (Sandbox Code Playgroud)
因此,这里我们使用掩盖df df['a'] == 1,这将返回一个布尔数组,然后掩盖df并仅选择column 'b':
In[179]:
df.loc[df['a'] == 1,'b']
Out[179]:
0 2
3 40
Name: b, dtype: int64
Run Code Online (Sandbox Code Playgroud)
然后直接下标索引:
In[180]:
df.loc[df['a'] == 1,'b'].index[1]
Out[180]: 3
Run Code Online (Sandbox Code Playgroud)
然后,我们可以将该索引标签传递回顶层loc。
这test[test.a == 1].b.iloc[[1]] = 3是链接索引,因此会发出警告。