import pandas as pd
import numpy as np
df = pd.DataFrame({'id':[1001,1002,1003,1004,1005,1006],
'date':pd.date_range('20130102', periods=6),
'city':['Beijing','SH','Guangzhou ','Shenzhen','Shanghai', 'Beijing'],
'age':[23,44,54,32,34,32],
'category':['100-A','100-B','110-A','110-C','210-A','130-F'],
'price':[1200,np.nan,2133,5433,np.nan,4432]},
columns =['id','date','city','category','age','price'])
# 更改列名称
df.rename(columns={'category': 'category-size',
'id':'user_id'}, inplace = True)
df = df.rename({'category':'category-size', 'id':'user_id'}, axis=1)
# 添加前缀或后缀
df.columns=['Z_'+i for i in df.columns]
df.add_prefix('X_')
df.add_suffix('_Y')
# 删除前缀与后缀
df.columns=[i.replace('_woe','') for i in df.columns]
df.columns = df.columns.str.replace('_woe','')
# 删除含有重复值的行
df.drop_duplicates(inplace = True) #保留重复的第一项
df.drop_duplicates(keep='last', inplace = True) #保留重复的最后一项
df.drop_duplicates(subset=['category']) #按某一列去重
# 删除行
df.drop(3, axis=0, inplace=True) #删除index=3的行
# 删除最后一行
df = df.drop([len(df)-1])
# 删除列
df.drop(['mob_province_x', 'order_id'], axis=1, inplace=True)
# 删除列名中含有'mob0'的列
if 'mob0' in df.columns.tolist():
df = df.drop('mob0', axis=1) #删除mob0
# 删除重名的列
df = df.loc[:, ~df.columns.duplicated()]
# 删除常数列
df = df.loc[:, df.apply(pd.Series.nunique)!=1]
# Jupyter Notebook中内嵌画图 %matplotlib inline
import missingno as msno
msno.matrix(df) #缺失矩阵
msno.bar(df) #缺失条形图
# 删除所有含缺失值的行
df = df.dropna()
# 删除数据表中整行都是空值的行
df = df.dropna(how='all')
# 删除所有含缺失值的列
df = df.dropna(axis=1)
# 删除缺失比例0.8以上的列
df = df.dropna(thresh=len(df)*0.2, axis=1)
# 使用数字-999填充数据表中空值
df.fillna(-999)
# 对某一列进行填充
df.fillna({'price':0})
# 根据含有缺失值 的两列进行填充
df['prov'] = df.apply(lambda x: x.prov2 if pd.isnull(x.prov1) else x.prov1, axis=1)
# 将0值替换为None
df['price'] = df['price'].map(lambda x: x if x != 0 else None)
# 将无效数据转换为NaN,再填充为0
df = df.apply(pd.to_numeric, errors='coerce').fillna(0)
# 多列同时替换
columns = ['price', 'city', 'category']
for col in columns:
df[col].replace([0], [None], inplace=True)
# 替换为标准缺失值格式
columns = ['col1', 'col2', 'col3']
for col in columns:
df[col].replace([None,'None','未知',''], np.nan, inplace=True)
df[col] = df[col].astype('float')
df[col].fillna(-999, inplace = True)
df[col] = df[col].astype('int')
# 批量转化为浮点格式
for i in df.columns:
try:
df[i] = df[i].apply(lambda x:float(x))
except:
pass
# 使用price均值对NA进行填充
df['price'].fillna(df['price'].mean(), inplace = True)
# 使用sklearn的Imputer缺失值填充
from sklearn.preprocessing import Imputer
imr = Imputer(strategy= 'median') # 'mean'
imr = imr.fit(df)
df_imr = imr.transform(df)
df_imr = pd.DataFrame(df_imr, columns = list(df.columns))
# 更改数据格式
df['price'] = df['price'].astype('int') #整数
df['price'] = df['price'].astype('float') #浮点数数
df['price'] = df['price'].astype('str') #字符串
# 设置特定数值格式
format=lambda x:'%.2f'% x #两位小数
df.applymap(format) #df里的所有数据都运用这个格式
df['price'].map(format) #df里的'price'列下面的所有数据都运用这个格式
df['percent']=df['price'].apply(lambda x: format(x,'.2%')) #转百分比
df['price'] = df['price'].apply(lambda x: round(x+0.001, 2)) #四舍五入
# 四舍五入
from decimal import Decimal, ROUND_HALF_UP
x = 577.575
Decimal(x).quantize(Decimal('0'), rounding=ROUND_HALF_UP)
Decimal(x).quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
# 清理空格
df['city']=df['city'].map(str.strip) #清理字符串两端的空格方法1
df['city']=df['city'].str.strip() #清理字符串两端的空格方法2
df['city']=df['city'].str.lstrip() #清理字符串左侧的空格
df['city']=df['city'].str.rstrip() #清理字符串右侧的空格
# 清理字符串中的特定字符
df['city'] = df['city'].str.strip('~') #清理字符串两端的~符号
# 清理字符串中的数字
import re
df['city'] = df['city'].apply(lambda x: re.sub(r'\d+', '', x))
# 清理数值中的特定符号
df['price'] = df['price'].replace('[$,RMB]', regex=True).astype('float')
# 清理数据中的换行符
df = df.apply(lambda x: x.replace(r'\N', np.nan))
# 清理所有异常字符
import string
exclude = set(string.punctuation)
def remove_punctuation(x):
x = ''.join(ch for ch in x if ch not in exclude)
return x
df['city'] = df['city'].apply(remove_punctuation)
# 在html格式中提取有效数据
import re
ccc = '<span class="text-warning"><i class="fa fa-circle"></i> 未知</span>'
x = re.sub('<[^<]+?>', '', ccc).replace('\n', '').strip()
# 清除整张表内所有数据为.0的后缀
df = df.applymap(lambda x: str(x).rstrip('.0'))
# 用空格填充字符串到固定长度
df['city']=df['city'].str.ljust(10) #原字符串左对齐,用空格填充至长度10
df['city']=df['city'].str.rjust(10) #原字符串右对齐,用空格填充至长度10
df['city']=df['city'].str.center(10) #原字符串居中,用空格填充至长度10
# 用特定字符填充字符串到固定长度
df['city']=df['city'].str.center(10, '~') #原字符串居中,用~填充至长度10
df['city']=df['city'].str.upper() #大写
df['city']=df['city'].str.lower() #小写
df['city']=df['city'].str.swapcase() #大小写互换
df['city']=df['city'].str.capitalize() #首字母大写
df['city']=df['city'].str.title() #字符串中的每个单词首字母大写
df.columns = df.columns.map(lambda x: x.lower()) #将列名统一改为小写
# 数据字符替换
df['city'].replace('sh', 'shanghai')
# 数据替换'sh'或者'hai' 替换成'shanghai'
df['city'].replace(['sh','hai'], 'shanghai')
# 根据映射替换
d = {'male': 0, 'female': 1}
df['gender2'] = df['gender'].map(d)
# 返回字符中某个字符的位置
df['city'].str.find('h')
# 提取某一列的第一个字符
df['city'].str.get(0)
# 判断第一个字符
df.loc[df['city'].str.startswith('S')]
df.loc[df['city'].map(lambda x: x[0])!='S']
# 提取前三个字符,并生成数据表
category = df['category']
pd.DataFrame(category.str[:3])
# 数据字符多重替换
data = pd.Series(['1,2,3', '2,3,4', '3'])
map = {'1': 'A', '2':'B', '3':'C', '4':'D'}
def rep(item):
if item.find(',') != -1:
lst = item.split(',')
rst = [map[x] for x in lst]
return ','.join(rst)
else:
return map[item]
data1 = data.map(lambda x: rep(x))
# 分类中出现次数较少的值归为others
freq = df['categories'].value_counts(normalize = True)
threshold = 0.1
small_categories = freq[freq < threshold].index
df['categories'] = df['categories'].replace(small_categories, 'others')
# 日期处理
from dateutil.relativedelta import MO
import datetime as dt
#今天
date = dt.datetime.now()
#昨天
date_m1 = (date+dt.timedelta(days=-1)).strftime('%Y-%m-%d')
#本周一
date_m7 = (date-pd.tseries.offsets.DateOffset(weekday=MO(-1))).strftime('%Y-%m-%d')
#本月1号
date_m30 = (date-pd.tseries.offsets.DateOffset(day=1)).strftime('%Y-%m-%d')
# 本月第一天
pd.datetime(2018,11,4)-pd.tseries.offsets.DateOffset(day=1)
#上月1号
date_m60 = (dt.date.today().replace(day=1) - dt.timedelta(1)).replace(day=1)
# 上月最后一个工作日
pd.datetime(2018,11,4)-pd.tseries.offsets.DateOffset(weekday=MO(-1))
# 上月的昨天
date_lastM = (date+dt.timedelta(days=-1))+pd.DateOffset(months=1)
# 调整日期格式
df["date"].map(lambda x : datetime.datetime.strptime(x, "%Y-%m-%d"))
import datetime
df['apply_date'] = df['apply_date'].map(lambda x : datetime.datetime.strptime(x, "%Y-%m-%d"))
df['apply_date'] = df['apply_date'].dt.strftime('%Y-%m-%d')
# 将20/9/2018 13:08:47转为月份格式
from datetime import datetime
df['time'] = df['time'].apply(lambda x: datetime.strptime(x, '%d/%m/%Y %H:%M:%S'))
df['month'] = df['time'].apply(lambda x: x.strftime('%Y-%m'))
#日期字符串'%Y-%m-%d'简写形式
from datetime import datetime
datetime.now().strftime('%F')
# 对含有日期空值NaT的处理,仅对有日期的数值进行转化
df.loc[~df['apply_date'].isna(),'apply_month'] = \
df.loc[~df['apply_date'].isna(),'apply_date'].map(lambda x: x.strftime('%Y年-%m月'))
# 八位数字转日期格式
from dateutil.parser import parse
a=20190613
b=str(a)
c=parse(b)
# Time
df['weekday'] = df['starttime'].apply(lambda s : s.weekday()) # Monday is 0 and Sunday is 6
df['hour'] = df['starttime'].apply(lambda s : s.hour)
df['day'] = df['starttime'].apply(lambda s : str(s)[:10])
# 计算天数
df['datediff'] = df['apply_date'] - df['shop_online_date']
df['datediff'] = df['datediff'].map(lambda x : x.days)
| < <目录 | 04-数据预处理 > | 返回顶部 ↑ |