处理缺失数据
判断数据缺失 isnull
log_data = pd.read_csv('log.csv') #读取数据
log_data.isnull() #判断数据缺失,结果为缺失的地方为TRUE
log_data['paused'].isnull() #判断某一列
判断数据缺失后,就可以通过布尔过滤过滤出来不为空的数据
log_data[log_data['volume'].notnull()] # 取出volume不为空的数据
处理缺失数据
- 扔掉空数据 df.dropna()
如果空数据太多,这样留下的数据会特别少
log_data.dropna() #一行里只要有一个数据为空,则扔掉此行
选B,不加inplace为TRUE的时候结果为A,但是加了以后他的返回值为None,因此cln_df为None,所以写程序时如果加了inplace为TRUE就不要给他赋值一个变量了
- 填充数据
① 用df.fillna()把NaN都变成0
log_data.fillna(0,inplace=True) #把NaN都变成0
②用df.ffill(),按之前的数据填充
log_data.ffill() #前面一行是啥此行就填啥
③用df.bfill(),按之后的数据填充
log_data.bfill() #后面一行是啥此行就填啥
④插值 interpolate
有线性插值等
- 数据变形
①处理重复数据
判断数据是否重复duplicated()
去除重复数据,drop_duplicates(),可在[]指定把哪几列重复的删掉,如何保留数据
data.drop_duplicates(['k1', 'k2'], keep='last') #把k1列和k2列重复的行去掉,并保留重复行中的最后一行
②使用函数或map转化数据,通常根据字典进行数据转化
使用map向数据中添加一个新的列
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
} #要添加的列,食物来自什么动物
lowercased = data['food'].str.lower() #把数据中的字母都变成小写
data['animal'] = lowercased.map(meat_to_animal) #直接用map进行映射
### 如果不提前把数据转成小写,也可以在map中进行转化
data['animal2'] = data['food'].map(lambda x: meat_to_animal[x.lower()])
③ 用replace()替换值
data.replace([-999, -1000], np.nan) #把-999和-1000都赋值为空
data.replace([-999, -1000], [np.nan, 0]) 或 data.replace({-999: np.nan, -1000: 0})# 将-999,-1000分别替换为空值和0
④离散化和分箱操作,pd.cut(),返回的是Categorical对象
也就是把序列中的数据根据设置的边界分到一个个的组中
<1>可以统计各个年龄段中人的数量
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] # 年龄数据
bins = [18, 25, 35, 60, 100] # 分箱的边界
cats = pd.cut(ages, bins) # 把年龄ages按照bins进行分组
# 统计箱中元素的个数
pd.value_counts(cats)
<2>带标签的分箱,即返回的数据时类别(比如年龄是老年还是中年
# 带标签的分箱
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
cats = pd.cut(ages, bins, labels=group_names) #加一个标签label
cats.get_values()
⑤哑变量操作,pd.get_dummies()
把分好的类变成机器能够识别的编码,如身高分为高中低,则哑变量操作会生成三列数据如001表示高,010表示中,100表示低
df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
'data1': range(6)})
data1 key
0 0 b
1 1 b
2 2 a
3 3 c
4 4 a
5 5 b
pd.get_dummies(df['key']) #进行哑变量操作
⑥向量化字符串操作
也就是把字符串看成一个整体进行操作
data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan}
data = pd.Series(data)
data.str.contains('gmail') #数据中是否包含gmail
split_df = data.str.split('@', expand=True) #把字符串用@分成两列
split_df[0].str.cat(split_df[1], sep='@') #连接