Python数据分析——Pandas数据预处理

Python数据分析——Pandas数据预处理

目录

  1. 特征选择/删除属性
  2. 缺失值处理
  3. 样本/数据选择
  4. 删除样本/数据
  5. 数据、属性、索引变换
  6. 字符型数据修改
  7. 数据合并、新增

1.特征选择/删除属性

(1)选择某个特征

features =['feature1','feature2','feature3','feature4'...]
data = data[features]  #往里传入的是列表!!
#注意pandas的Dataframe[]里接受的是列表!!,直接输入属性名的时候别忘了两个[[]]

(2)更改属性列的顺序

order = ['feature3','feature2','feature2']
data=data[order]

(3)删除某一列

data.drop(['ID'],inplace=True,axis=1)#删除ID属性所在的列

(4)删除只有一个值的属性

original_column = data.columns
drop_column = []
for col in original_column:
    feature_values = data[col].dropna().unique() 
# 1.dropna删除缺失值Nan;2.unique看data[col]这个Series中有几种值:返回的是list
    if len(feature_values) ==1:
        drop_column.append(col)
data = data.drop(drop_column, axis=1)
print(drop_column) #打印被删除的列是哪些

2.缺失值处理

处理方法:
直接剔除缺失值
插补:可用均值、中位数等来填充缺失值
删除操作:
(1)只要有缺失值,就删除该行

data.dropna(inplace=True)

(2)样本中有x个以上的缺失值才删除该行

data.dropna(axis=0,thresh=x,inplace=True)##样本中至少x个值是非缺失的才保留

(3)所有数据都缺失才删除该行

data.dropna(inplace=True,how='all')

(4)找到属性值缺失x%的才删除

null_cols = [col for col in data.columns if data[col].isnull().sum() / data.shape[0] > 0.9] # 一个属性中NaN缺失值的个数/样本总数=缺失比率>0.9

填充操作:
(1)均值插补

data['Attribute_name'].fillna(data['Attribute_name'].mean(),inplace=True)

(2)使用缺失值的前一个/后一个值代替缺失值

data.fillna(method='pad') #用前一个值替代NaN
data.fillna(method='bfill') #用后一个值替代NaN

(3)传入字典,对不同的列填充不同的值

data.filna({"Attributed_named1":fill_value1,"Atributed_named2":fill_value2...})
#一般不用这种方法插补,常用fillna

(4)用groupby定位特定的样本群,求统计量后填充缺失值
数据中Age缺失的有点多,思想是:将那些与缺失Age样本具有同样Sex和Pclass的群体样本的Age中位数来填充,比如说有个样本缺失Age,它的Sex=female,Pclass=1;那么groupby找到对应的一群样本,求这群样本的Age中位数然后填充缺失值

data['Age'] = data.groupby(['Sex', 'Pclass'])['Age'].apply(lambda x: x.fillna(x.median()))

3.样本/数据选择

request_data = data.query("feature1 <= num_value1 & feature2== 'str_value2'")

chosen_samples = data[data[attirbute_name] == specific_value]
#比较运算法==,<,>,!=...
chosen_samples = data.loc[data['feature_name']=='particular_value']

chosen_samples = data[data.attirbute_name.between(start,end)]
null_data = data[data[attirbute_name].isnull()]#选择某个属性为空的样本
data = data[(condition1)&(condition2)]    #逻辑运算and / or / not 

(1)根据属性A==某值,来找到该样本下属性B的值

df.query("姓名=='刘星'")['数学'].values[0]#找到姓名为刘星的样本,他的数学成绩为多少

(2)获取包含特定字符str的样本

data = data[data[attirbute_name].str.contains("special_words",na=False)]

(3)使用索引index选取数据

data1 = data.iloc[x,y]  #选取第x+1行,第y+1列
data2 = data.iloc[[x1,x2],:] # 选取第x1+1和第x2+1行,所有列
data3 = data.iloc[x1:x2,:]  #选取第x1+1行 到 x2+1行的所有数据,所有列
series4 = data.iloc[:,y]  #选取数据的第y+1列的值,返回的是Series
series5 = data.iloc[x,:]  #选取数据的第x+1行的值,返回的是Series

(4)使用索引index选取数据

df = data.loc[label_value_x:label_value_y, ] #获取x行到y行之间的所有样本
df = data.loc[:,attribute_name] #选取attribute_name该列的所有数据

(5)随机抽取样本

samples = DataFrame.sample(n,frac,replace,random_state,axis)
#n:要抽取的样本数量
#frac:抽取的比例
#replace:是否有放回,True为放回抽样,默认False
#axis[0,1]控制抽取行(0),列(1)

random_factor = numpy.random.randint(start,end,num)  
#start,end是要抽取得范围的索引;num是要抽取的个数
samples = data.loc[random_factor,:]    #也可以直接写成data.loc[random_factor]

4.删除样本/数据

(1)根据索引行删除

data=data.drop(2)   #删除索引行为2的样本

(2)删除重复样本

data.drop_duplicates(subset=None,keep='first',inplace=False)
  • subset:传入的是列名列表[“column_name1”,“column_name2”], 表示几个列合在一起考虑是否有重复值:例如: subset指定[‘sex’,‘id’,‘age’]如果有多个样本中:ID相同,Sex相同,Age相同,才删除重复样本
  • keep:默认是first表示除了第一个出现的值,其他的重复的样本都删除;还可选’last’
    或keep = False:表示所有的重复样本都删除
  • inplace :控制是否就地修改

(3)按照某个属性的特定值删除样本

data = data[data.attirbute_name != specific_value]
#例:
data = data [(data.军训!="缺考")&(data.体育!="作弊")]   #删除数据中军训是缺考,体育是作弊的样本

(4)删除属性值过于单一的属性
逐列的寻找,看哪些列的属性值分布太过单一,比如说记录分数score属性的列,90%以上都是B,那么这一列就没什么用处,太单调了

most_value_col = [col for col in train_data.columns if train_data[col].value_counts(dropna=False, normalize=True).values[0] > 0.9]

(5)删除包含特定字符串的样本

data = data[~data['comment'].str.contains('xxx')]

5.数据、属性、索引变换/修改

(1)One-hot变换,离散值处理
先筛选出dtypes是’object’的属性,返回的是复制的Dataframe

obj_df = df.select_dtypes(include=['object']).copy()
pd.get_dummies(obj_df, columns=["col_1", "col_2"...], prefix=["name1", "name2"])
#columns:控制哪些属性进行one-hot变换;可以不传,全用obj_df的属性进行变换
#prefix:控制新生成的属性的前缀

LabelEncoder变换(有顺序的)

from sklearn.preprocessing import LabelEncoder

obj_df = train_data.select_dtypes(include=['object']).copy()
categorical_cols = obj_df.columns.tolist()

for col in categorical_cols:
    if col in train_data.columns:
        le = LabelEncoder()
        le.fit(list(train_data[col].astype(str).values) + list(test_data[col].astype(str).values))
        train_data[col] = le.transform(list(train_data[col].astype(str).values))
        test_data[col] = le.transform(list(test_data[col].astype(str).values))
#因为sklearn的LabelEncoder只能一列一列转换,就需要用到apply对所有目标列进行转换
x=df.apply(LabelEncoder().fit_transform)

(2)利用map字典,将某列数据转换成别的值
在这里插入图片描述

dict = {'中国':'China','日本':'Japan','韩国':'Korea'......}
data['国家'] = data['国家'].map(dict)
#tips: 一开始找到的字典是英中对照的{‘China’: ‘中国’, ‘Japan’: ‘日本’, ‘Korea’: ‘韩国’…},要先进行key,value对换
dict = {'China': '中国', 'Japan': '日本', 'Korea': '韩国'......}
dict = {x:y for y,x in dict.items()}

(3)利用replace进行数据替换
相当于word中的(ctrl+h)替换操作

data.replace("value_A","value_B")  #用B替换A  也可以传入{"value_A":"value_B"}
data['..'] = data[["atrribute1","atrribute2"...]].replace("value_A","value_B")  #inplace=True 就地修改

多列同时替换, 用value_new替换属性1的value1值和属性2的value2值

data = data.replace({"attribute_name_1":"value1","attribute_name_2":"value2"},'value_new')

多值同时替换

data.loc[data['feature_name'] =><!= condition,'feature_name'] = 'new_value'

(4)根据条件值更改

data.loc[data['feature_name'] =><!= condition,'feature_name'] = 'new_value'

Alt

#将reading score<50的更改成F
data.loc[data['reading score'] < 50, 'reading score'] = 'F'

(5)整列替换

data["attribute_name"] = new_value #new_value 是列表或者Series序列或一个特殊值

(6)eval()列之间的数值运算

result = pd.eval('df1+df2/df3.....') #eval处理的是字符串   支持&与,|或运算符
#传入eval的字符串里也可以使用属性索引df.iloc[2],也支持列间运算df.feature1 +df.feature2

#注意好像eval中不能用data[‘feature’],只能用属性data.feature的形式,或者可以:
resut = data.eval('feature1 + feature2')

#例:
pd.eval("(data.reading_score + data.writing_score)/2")
data.eval("(reading_score + writing_score)/2")
#也可利用eval()将计算结果作为新增列,如下会新增一列feature4
data.eval('feature4 = (feature1+feature2)/feature3',inplace = True)
#eval()还可使用局部变量进行计算
local_mean = data['feature'].mean()
result = data.eval('feature2 +@local_mean')

(7)pd.cut分割数值型数据并赋值分组

#例:将成绩分成A,B,C
bins = [min(df["attribute_name"]),60,70,80,max(df["attribute_name"])+1]
level = ["不及格","及格","良好","优秀"]
result =pd.cut(df["attribute_name"],bins,right=False,labels=level)
df["result"] = result

(8)将某一列设置为索引

#指定某一列为索引,以便于其他数据进行操作
data = data.set_index("attribute_name")  #指定一列作为DataFrame的索引
#可传入drop=False,保留被作为索引的列;append=True:保留原本的索引,并增加新的索引列

(9)修改属性名

#少量修改个别属性的名字
data.rename(columns={'old name':'new name','old name2':'new name2'},inplace=True)
#大量修改属性名
new_column_name = ['col_1','col_2','col_3'....]
data.columns = new_column_name

(10)对data进行重新排序

data.sort_index()  #按照默认索引index升序排列,降序:往里传入ascending=False
data.sort_index(by="attribute_name")  #按某列属性的值的大小进行排列,也可传入列表,进行多列排列
data.sort_index(axis=1) #根据列名的字母顺序,对列进行排列 

data.reset_index() 

(11)对数据中的无穷大/小的替换

#将数据集中出现的无穷大和无穷小替换成缺失值
#np.inf : 是无穷大的意思
def clean_inf_nan(df):
    return df.replace([np.inf, -np.inf], np.nan)

6.字符型数据修改

(1)清除字符型数据首尾两端指定的字符,默认为空格

data["attribute_name"].str.strip()  #删除首尾空格
data["attribute_name"].str.rstrip() #lstrip()
data["attribute_name"].str.strip("s") #删除首尾的s字符

(2)截取(slice)字符串数据的部分字段

#例:截取手机号各个位数,前三位品牌(186联通),中四位表示地区(0315太原),后四位才是号码
data["电话"] =data["电话"].astype(str) #数字转字符串
first_three = data["电话"].str.slice(0,3)

(3)String数据按照指定的字符进行拆分(split)

data["attribute_name"].str.strip()  #删除首尾空格
newDF = data["attribute_name"].str.split("sep",n,expand=False)
#sep表示用于分割字符串的分隔符 比如空格 点 斜杠 .\
#n表示分割后新增的列数
#expand为True返回DataFrame,默认为False返回Series
#分割后生成的列,用newDF.columns = [“attribute_name1”,”attribute_name2”…]重命名后再整合回去

(4)多列字符型数据合并

在这里插入代码片data["xing_ming"] = data["xing"]+data["ming"]

(5)替换

data.columns = data.columns.str.replace(' ','_')

(6)对Str型数据的操作

data['str_feature'].str.method()  # method() = strip/split/upper/lower.....

7.数据合并、新增

(1)pd.concat()相关应用

pd.concat([df1,df2],axis=0)  #如果df1,df2列名相同;简单的将df2添加到df1的下方
new_data = pd.concat([df1,df2],axis=1) #将df2按列添加,添加到df1的右边
data = pd.concat([data1,data2],ignore_index=True) #合并数据1和2,并新建一个整数索引
new_data = pd.concat([ data1.loc[:x],data2,data1.loc[x+1:] ],ignore_index=True)  #往data1里面插入data2,插入节点在x+1处

##列名不完全相同的数据进行合并
new_data = pd.concat([df1,df2], join='outer') #默认join参数'outer'取并集;'inner'是取交集
new_data = pd.concat([df1,df2], join_axes=[df1.columns])   #指定按照df1的列来合并
new_data = pd.concat([df1,df2], join_axes=[specific_column_name_list]) #指定合并后保留的列

(2)pd.merge()

merge_data = pd.merge(df1,df2,on='feature')#两个数据集具有相同名字的属性

(3)新增一列属性

data['new_feature'] = series_values

(4)apply新增列

def valuation_formula(x, y):    
	return x * y * 0.5
df['price'] = df.apply(lambda row: valuation_formula(row['x'], row['y']), axis=1)	

原文链接:link

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值