[Pandas]Dataframe赋值

在进行Titanic幸存者预测的过程中,数据预处理涉及到空值填充。我的想法是以Pclass分组,为Age的空值填充随机值x~U(mean-σ,mean+σ)


一、warning

开始是参考其他文章的做法,但情况不一样,那篇文章并没有分组赋值,由于不涉及分组,所以对dataframe赋值时是一整列进行赋值的,而这是pandas官方建议的赋值方法之一

import pandas as pd
import numpy as np


train_data = pd.read_csv('data/train.csv')

for pclass in train_data.Pclass.unique():
    class_age = train_data['Age'][train_data.Pclass == pclass]
    age_null = class_age.isnull().sum()
    mean = class_age.mean()
    std = class_age.std()
    randage = np.random.randint(mean - std, mean + std, size=age_null)
    age_slice = class_age.copy()
    age_slice[np.isnan(age_slice)] = randage
    train_data['Age'][train_data.Pclass == pclass] = age_slice

在for循环的最后一行

train_data['Age'][train_data.Pclass == pclass] = age_slice

等号左边由于有[train_data.Pclass == pclass],因此是一个Dataframe的切片(slice),对一个切片赋值会有如下警告,当然这种赋值是可以完成的,但我想要使用官方推荐的方法来完成

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

二、

1.取值赋值

Dataframe取值赋值有多种方法,但我认为可以分为两类
第一类:使用方括号[]

# 取一列
df.B
df[B]
# 设置条件
df.B[df.A>4]
df.B[df.A>4][df.B.isnull()]

第二类:使用函数.loc()/.iloc()(本文不讨论两者区别)

# 使用索引
df.iloc[2,2]
# 使用索引名
df.loc['一','B'] 
# 取多行
df.loc[:,"年龄"]

2. .loc()

pandas官方的建议是使用.loc()来完成。
.loc()可以读取指定位置的值,也可以对指定位置进行赋值
.loc()的第一个参数(index)指定行,第二个参数(columns)指定列,而且使用:取多行/列时,是"前闭后闭",也就是:两边都能取到

但我希望的是为行添加多个条件
这是能办到的,如下

mask = (df.A==a)&(df.b>20)&(df.c.isnull())
df.loc[mask,'d']

注意各条件使用()括起来,如果条件简单,不使用mask也是可行的,如

df.d.loc[(df.d>20)&(df.d<=30)]

那么我的原代码,在for循环的最后三行改为以下代码即可

mask = (train_data.Pclass == pclass) & (train_data.Age.isnull())
train_data.loc[mask, 'Age'] = randage

参考:
1.最底下是解决方法(全英)
2.这个pdf就一页,可以试读全部
3.其他赋值方法
4.查找有空值的行
5.空值判断

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值