環境
- 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 |