环境
- Anaconda notebook
- Python 3.6
- pandas 0.20.0
问题:
筛选出符合某些条件的行以后,对这些行里面的某一列进行数值修改时,如果直接使用 data[筛选条件][某一列] = 值
会出现错误,因为这是对切片拷贝进行操作。因此,需要使用 .loc[]
来解决筛选、并原地修改数值的问题。
1 准备数据
把下列内容填入 Sublime Text 等编辑器,另存为 test.csv 文件。
id,sex,age
1,male,11
2,female,
3,female,31
4,male,21
5,male,
2 读入数据
import pandas
data = pd.read_csv('test.csv')
查看读入的数据
data
得到
id | sex | age | |
---|---|---|---|
0 | 1 | male | 11.0 |
1 | 2 | female | NaN |
2 | 3 | female | 31.0 |
3 | 4 | male | 21.0 |
4 | 5 | male | NaN |
3 是否使用 .loc[]
的区别
假设,我们需要筛选出所有的男性(sex=male),并将其 id 改为 100。
3.1 没有使用 .loc[]
的情况
如果我们没有使用 .loc[]
,直接使用 []
进行数据切片选择,并对其赋值,就会产生错误。
# 设置筛选条件:选择 sex 为 male
mask = (data['sex']=='male')
# 查看筛选情况,选出了 sex 为 male 的数据
data[mask]
id | sex | age | |
---|---|---|---|
0 | 1 | male | 11.0 |
3 | 4 | male | 21.0 |
4 | 5 | male | NaN |
对其赋值
data[mask]['id'] = 100
出现警告,称切片仅仅是拷贝,不能对其赋值,需要 .loc[row_indexer,col_indexer] = value
赋值
/Users/mac/anaconda/lib/python3.6/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
"""Entry point for launching an IPython kernel.
3.2 使用 .loc[,]
赋值,成功
使用方法是
data.loc[筛选条件, 赋值列名] = 值
对 test.csv 操作:筛选出所有的男性(sex=male),并将其 id 改为 100。
# 设置筛选条件:选择 sex 为 male
mask = (data['sex']=='male')
# .loc[] 赋值
data.loc[mask, 'id'] = 100
结果:
id | sex | age | |
---|---|---|---|
0 | 100 | male | 11.0 |
1 | 2 | female | NaN |
2 | 3 | female | 31.0 |
3 | 100 | male | 21.0 |
4 | 100 | male | NaN |