将值为0的数据替换为空值
data = data.replace(0.0000, np.nan)
统计某一列空值的数量
data['one_column'].isnull().sum()
统计缺失值大于某一阈值的列的名字
data_null = []
for data_col in data.columns.values.tolist():
if data[data_col].isnull().sum() >= 16:
data_null.append(data_col)
print(data_col, data[data_col].isnull().sum())
data_null
删除某一列或批量删除某几列
data = data.drop('one_column',axis=1)
data = data.drop(data_null,axis=1)
用均值填充缺失值
avg = data[null_colums].mean()
data[null_colums] = data[null_colums].fillna(avg)
缺失值分析
def missing_values(df):
alldata_na = pd.DataFrame(df.isnull().sum(), columns={'missingNum'})
alldata_na['existNum'] = len(df) - alldata_na['missingNum']
alldata_na['sum'] = len(df)
alldata_na['missingRatio'] = alldata_na['missingNum']/len(df)*100
alldata_na['dtype'] = df.dtypes
#ascending:默认True升序排列;False降序排列
alldata_na = alldata_na[alldata_na['missingNum']>0].reset_index().sort_values(by=['missingNum','index'],ascending=[False,True])
alldata_na.set_index('index',inplace=True)
return alldata_na
missing_values(data_train)
是否有单调特征列(单调的特征列很大可能是时间)
#是否有单调特征列(单调的特征列很大可能是时间)
def incresing(vals):
cnt = 0
len_ = len(vals)
for i in range(len_-1):
if vals[i+1] > vals[i]:
cnt += 1
return cnt
fea_cols = [col for col in data_train.columns]
for col in fea_cols:
cnt = incresing(data_train[col].values)
if cnt / data_train.shape[0] >= 0.55:
print('单调特征:',col)
print('单调特征值个数:', cnt)
print('单调特征值比例:', cnt / data_train.shape[0])
特征nunique分布
# 特征nunique分布
for feature in categorical_feas:
print(feature + "的特征分布如下:")
print(data_train[feature].value_counts())
plt.hist(data_all[feature], bins=3)
plt.show()
统计特征值出现频次大于100的特征
# 统计特征值出现频次大于100的特征
for feature in categorical_feas:
df_value_counts = pd.DataFrame(data_train[feature].value_counts())
df_value_counts = df_value_counts.reset_index()
df_value_counts.columns = [feature, 'counts'] # change column names
print(df_value_counts[df_value_counts['counts'] >= 100])
Labe 分布
# Labe 分布
fig,axes = plt.subplots(2,3,figsize=(20,5))
fig.set_size_inches(20,12)
sns.distplot(data_train['tradeMoney'],ax=axes[0][0])
sns.distplot(data_train[(data_train['tradeMoney']<=20000)]['tradeMoney'],ax=axes[0][1])
sns.distplot(data_train[(data_train['tradeMoney']>20000)&(data_train['tradeMoney']<=50000)]['tradeMoney'],ax=axes[0][2])
sns.distplot(data_train[(data_train['tradeMoney']>50000)&(data_train['tradeMoney']<=100000)]['tradeMoney'],ax=axes[1][0])
sns.distplot(data_train[(data_train['tradeMoney']>100000)]['tradeMoney'],ax=axes[1][1])
转换object类型数据为LabelCode
将取值具有大小意义的类别型变量数据转变为数值型映射,可使用LabelEncoder对不具实体数值数据编码
LabelEncoder是用来对分类型特征值进行编码,即对不连续的数值或文本进行编码。其中包含以下常用方法:
fit(y) :fit可看做一本空字典,y可看作要塞到字典中的词。
fit_transform(y):相当于先进行fit再进行transform,即把y塞到字典中去以后再进行transform得到索引值。
inverse_transform(y):根据索引值y获得原始数据。
transform(y) :将y转变成索引值。
>>> le = preprocessing.LabelEncoder()
>>> le.fit(["paris", "paris", "tokyo", "amsterdam"])
LabelEncoder()
>>> list(le.classes_)
['amsterdam', 'paris', 'tokyo']
>>> le.transform(["tokyo", "tokyo", "paris"])
array([2, 2, 1]...)
>>> list(le.inverse_transform([2, 2, 1]))
['tokyo', 'tokyo', 'paris']
转换object类型数据为one-hot编码
有一些特征并不是以连续值的形式给出。例如:人的性别 [“male”, “female”],来自的国家 [“from Europe”, “from US”, “from Asia”],使用的浏览器[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]。这种特征可以采用整数的形式进行编码,如: [“male”, “from US”, “uses Internet Explorer”] 可表示成 [0, 1, 3] ,[“female”, “from Asia”, “uses Chrome”] 可表示成[1, 2, 1]。 但是,这些整数形式的表示不能直接作为某些机器学习算法输入,因为有些机器学习算法是需要连续型的输入数据,同一列数据之间数值的大小可代表差异程度。如: [0, 1, 3]与[0,1,0]的特征差异比[0, 1, 3]与[0,1,2]之间的差异要大,但事实上它们的差异是一样的,都是浏览器使用不一样。
一个解决办法就是采用OneHotEncoder,这种表示方式将每一个分类特征变量的m个可能的取值转变成m个二值特征,对于每一条数据这m个值中仅有一个特征值为1,其他的都为0。
对于类别离散型特征,取值间没有大小意义的,可采用one-hot编码
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder(handle_unknown='ignore')
>>> X = [['Male', 1], ['Female', 3], ['Female', 2]]
>>> enc.fit(X)
OneHotEncoder(handle_unknown='ignore')
>>> enc.categories_
[array(['Female', 'Male'], dtype=object), array([1, 2, 3], dtype=object)]
>>> enc.transform([['Female', 1], ['Male', 4]]).toarray()
array([[1., 0., 1., 0., 0.],
[0., 1., 0., 0., 0.]])
>>> enc.inverse_transform([[0, 1, 1, 0, 0], [0, 0, 0, 1, 0]])
array([['Male', 1],
[None, 2]], dtype=object)
>>> enc.get_feature_names_out(['gender', 'group'])
array(['gender_Female', 'gender_Male', 'group_1', 'group_2', 'group_3'], ...)
MinMaxScaler()
功能是将每个元素(特征,feature)转换成给定范围的值。分别缩放和转换每个特征,以使其处于训练集的给定范围内,例如在区间[0,1]。
>>> from sklearn.preprocessing import MinMaxScaler
>>> data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
>>> scaler = MinMaxScaler()
>>> print(scaler.fit(data))
MinMaxScaler()
>>> print(scaler.data_max_)
[ 1. 18.]
>>> print(scaler.transform(data))
[[0. 0. ]
[0.25 0.25]
[0.5 0.5 ]
[1. 1. ]]
>>> print(scaler.transform([[2, 2]]))
[[1.5 0. ]]
时间格式预处理
#将update_date从例如2019-02-20的str变为datetime格式,并提取处year、month、day
data["year"] = pd.to_datetime(data["update_date"]).dt.year
data["month"] = pd.to_datetime(data["update_date"]).dt.month
data["day"] = pd.to_datetime(data["update_date"]).dt.day
data['week'] = pd.to_datetime(data["update_date"]).dt.week
data['weekday'] = pd.to_datetime(data["update_date"]).dt.weekday
找出 year 中2019年以后的数据,并将其他数据删除
data = data[data["year"] >= 2019] #找出 year 中2019年以后的数据,并将其他数据删除
聚合时间数据
# 聚合时间数据
total_balance = data.groupby(['date'])['total_purchase_amt','total_redeem_amt'].sum().reset_index()
将时间字符串转换为10位时间戳
import time
#将时间字符串转换为10位时间戳,时间字符串默认为2017-10-01 13:37:04格式
def date_to_timestamp(date, format_string="%Y/%m/%d %H:%M:%S.%f."):
time_array = time.strptime(date, format_string)
time_stamp = int(time.mktime(time_array))
return time_stamp
数据导入和预览
数据的列columns属性
数据的空值检测
空值的替换方式
异常值的处理方式
3segama原则
箱型图
任意数据的增删改查
处理后数据的导出
数据的归一化、标准化
数据分桶
数据正态分布
离散型、连续性数据和非数值数据
数据透视图