文章目录
本学习笔记为阿里云天池龙珠计划Docker训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/activity/promotion/aicampdocker
一、学习知识点概要:
熟悉pandas、numpy、seaborn等库的使用,学会对数据进行分类型处理
二、学习内容:
1、读取文件
- 通过nrows和usecols读取大块文件
#当文件特别大时,可以利用nrows参数来调节读取文件的前几行
data_train_sample = pd.read_csv("train.csv",nrows=5,usecols=['id'])
#此处令输出的参数为前五行,输出id一列
- 通过chunksize参数,来控制数据块的大小
chunker = pd.read_csv("train.csv",chunksize=5)
#此处将数据框的大小定义为五行
2、了解数据大致内容
- 查看数据集的样本个数
data_train.shape
#运行结果为:(80000,47),意味着有47列,80000行数据。
- 查看数据集的具体列名
data_train.columns
- 利用info()函数来查看数据的类型
data_train.info()
info()函数会输出的类型有int64、float64以及object
- 利用describe()函数查看各个特征的基本统计量
data_train.describe()
结果如图,其中count是数据量、mean是平均值、std是标准差、min是最小值、25%是四分之一分位数、max是最大值
- 利用print(f’’),使得字符串里面用花括号括起来的变量和表达式可表达
print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')
#输出为:There are 22 columns in train dataset with missing values.
print('There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')
#输出为:There are {data_train.isnull().any().sum()} columns in train dataset with missing values.此时花括号中的内容无法表达
#isnull().any().sum()会告诉我们含有缺失值的列数
#isnull().sum()就更加直观了,它直接告诉了我们每列缺失值的数量。
- 查看大体特征的缺失率
have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict()
fea_null_moreThanHalf = {}
for key,value in have_null_fea_dict.items():
if value > 0.5: #其中0.5代表查看缺失率大于50%的特征
fea_null_moreThanHalf[key] = value
fea_null_moreThanHalf
- 将缺失特征值的特征可视化
missing = data_train.isnull().sum()/len(data_train)
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
可视化结果:
经过可视化后,可以了解到哪些特征存在缺失,缺失率大概又是多少。如果缺失值过多,那么这一项特征对于数据的分析就几乎不起作用了,而缺失值很小时,一般可以选择填充。
- unique()和unique()统计不同值
unique()返回的时候不同值组成数组
nunique()返回的是不同值的个数
3、分析数据
- 将数据分类
#数值型数据
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
#非数值型数据
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
- 对数值型数据分为连续型及非连续型
def get_numerical_serial_fea(data,feas):
numerical_serial_fea = [] #连续型数值
numerical_noserial_fea = [] #非连续型数值
for fea in feas:
temp = data[fea].nunique()
if temp <= 10:
numerical_noserial_fea.append(fea)
continue
numerical_serial_fea.append(fea)
return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(data_train,numerical_fea)
- 查看非连续型数值的数值及分布状况,以便筛选无用变量
numerical_noserial_fea #查看有哪些数据是非连续型的
data_train[''].value_counts()
#相差悬殊、或全部一值的数据,则在后面的数据分析中不再进行分析
- 数字特征可视化
#每个数字特征得分布可视化
f = pd.melt(data_train, value_vars=numerical_serial_fea)
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
#分析每一个变量的分布类型,如果变量不太符合正态分布,可以log化后再观察一下是否符合正态分布。(如果想统一处理一批数据变标准化 必须把这些之前已经正态化的数据提出。正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。)
#对比不符合正态分布的数据,log化后的分布
plt.figure(figsize=(16,12))
plt.suptitle('Transaction Values Distribution', fontsize=22)
plt.subplot(221)
sub_plot_1 = sns.distplot(data_train['loanAmnt'])
sub_plot_1.set_title("loanAmnt Distribuition", fontsize=18)
sub_plot_1.set_xlabel("")
sub_plot_1.set_ylabel("Probability", fontsize=15)
plt.subplot(222)
sub_plot_2 = sns.distplot(np.log(data_train['loanAmnt']))
sub_plot_2.set_title("loanAmnt (Log) Distribuition", fontsize=18)
sub_plot_2.set_xlabel("")
sub_plot_2.set_ylabel("Probability", fontsize=15)
- 变量分布可视化
单一变量分布可视化
plt.figure(figsize=(8, 8))
sns.barplot(data_train["employmentLength"].value_counts(dropna=False)[:20],
data_train["employmentLength"].value_counts(dropna=False).keys()[:20])
plt.show()
查看类别型变量在不同y值上的分布
train_loan_fr = data_train.loc[data_train['isDefault'] == 1]
train_loan_nofr = data_train.loc[data_train['isDefault'] == 0]
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 8))
train_loan_fr.groupby('grade')['grade'].count().plot(kind='barh', ax=ax1, title='Count of grade fraud')
train_loan_nofr.groupby('grade')['grade'].count().plot(kind='barh', ax=ax2, title='Count of grade non-fraud')
train_loan_fr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax3, title='Count of employmentLength fraud')
train_loan_nofr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax4, title='Count of employmentLength non-fraud')
plt.show()
查看连续型变量在不同y值上的分布
fig, ((ax1, ax2)) = plt.subplots(1, 2, figsize=(15, 6))
data_train.loc[data_train['isDefault'] == 1] \
['loanAmnt'].apply(np.log) \
.plot(kind='hist',
bins=100,
title='Log Loan Amt - Fraud',
color='r',
xlim=(-3, 10),
ax= ax1)
data_train.loc[data_train['isDefault'] == 0] \
['loanAmnt'].apply(np.log) \
.plot(kind='hist',
bins=100,
title='Log Loan Amt - Not Fraud',
color='b',
xlim=(-3, 10),
ax=ax2)
4、时间格式数据处理及查看
#转化成时间格式 issueDateDT特征表示数据日期离数据集中日期最早的日期(2007-06-01)的天数
data_train['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days
#转化成时间格式
data_test_a['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
data_test_a['issueDateDT'] = data_test_a['issueDate'].apply(lambda x: x-startdate).dt.days
plt.hist(data_train['issueDateDT'], label='train');
plt.hist(data_test_a['issueDateDT'], label='test');
plt.legend();
plt.title('Distribution of issueDateDT dates');
#train 和 test issueDateDT 日期有重叠 所以使用基于时间的分割进行验证是不明智的
5、利用透视图了解数据
#透视图 索引可以有多个,“columns(列)”是可选的,聚合函数aggfunc最后是被应用到了变量“values”中你所列举的项目上。
pivot = pd.pivot_table(data_train, index=['grade'], columns=['issueDateDT'], values=['loanAmnt'], aggfunc=np.sum)
6、用pandas_profiling生成数据报告
import pandas_profiling
pfr = pandas_profiling.ProfileReport(data_train)
pfr.to_file("./example.html")
三、学习思考与总结:
这一次任务让我熟悉了对不同类型的数据进行分类、处理以及熟悉对matplotlib的使用。在有一定的python基础的前提下还算轻松。