<Python数据分析实战Tricks个人总结>

Python数据分析实战Tricks总结

matplotlib & seaborn 可视化

matplotlib 图内中文乱码显示:

  • 在最开始处加上以下代码:
# plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
# plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

词云可视化

  • 词云:只是简单根据词频进行可视化展示,没有去除停用词等
from wordcloud import WordCloud
# greatcloud = WordCloud(width=2400,height=1400,relative_scaling=.5).generate(str(sub_df['review_body']))
# plt.imshow(greatcloud,interpolation='bilinear')
# plt.axis('off')
# plt.show()

相关性图 / 变量分布图 / 箱线图

  • 图像详细可参考:Python统计分析可视化库seaborn

  • 多属性相关性:
    • 协相关矩阵(各个相关系数,默认皮尔逊)
    • sns.pariplot:分布图+相关点图 - 还可以根据不同索引画在一张图上
    • sns.heatmap:相关性热力图(适合多变量相比,因为相关性最低的区域一定是黑色),协相关矩阵的可视化表达
    • sns.clustermap:分层相关性热力图,了解不多
    • sns.PairGrid:网格化相关性图,可以分别在上中下使用不同的图像类型
  • 单个属性的分布:
    • sns.distplot:分布图+参数拟合(kde=False,则不展现拟合线)
    • sns.countplot:计数分布图(离散型数据)
    • sns.rugplot:展示原始的数据离散分布(dist是域分布,这里是边缘分布,更加实际离散)
    • sns.kdeplot:内核密度估计图,也显示了统计分布
  • 两两属性的相关性图:
    • sns.joinplot:相关分布图(数值与数值型)
      • kind:默认,点图
      • kind:'hex',深度频次图
      • kind:'reg',点图+简单回归线
      • kind:‘kde’,核密度分布图
    • sns.boxplot:箱线图(hue也可以加上不同属性对应的箱线图)(以下都是数值与离散值型)
    • sns.voilinplot:小提琴图,结合了boxplot图和密度痕迹,也可以用hue表示不同属性对应图
    • sns.stripplot:离散散点图,hue属性
    • sns.swarmplot:与stripplot类似,但是他不会重叠数据点,stripplot会重叠一样的数据
    • sns.factorplot:类似与PairGrid,可以显示任何想要的图像类型
sns.pairplot(tips) 
sns.pairplot(tips ,hue ='sex', markers=["o", "s"]) # markers颜色
sns.heatmap(tips.corr())
sns.clustermap(tips.corr())

g = sns.PairGrid(tips)
g.map_diag(sns.distplot)
g.map_upper(plt.scatter)
g.map_lower(sns.kdeplot)

sns.distplot(tips['total_bill'])
sns.distplot(tips['total_bill'],kde = False)
sns.countplot(x = 'smoker', data = tips)
sns.rugplot(tips['total_bill'])
sns.kdeplot(tips['total_bill'], shade=True)

sns.jointplot(x = 'total_bill', y = 'tip', data = tips)
sns.jointplot(x = 'total_bill', y = 'tip', data = tips ,kind = 'hex')
sns.jointplot(x = 'total_bill', y = 'tip', data = tips ,kind = 'reg')
sns.jointplot(x = 'total_bill', y = 'tip', data = tips ,kind = 'kde')

sns.boxplot(x = 'day', y= 'total_bill', data = tips)
sns.boxplot(x = 'day', y= 'total_bill', data = tips, hue = 'sex')
sns.violinplot(x = 'day', y= 'total_bill', data = tips)
sns.violinplot(x = 'day', y= 'total_bill', data = tips, hue = 'sex', split = True)
sns.stripplot(x = 'day', y = 'total_bill', data = tips)
sns.stripplot(x = 'day', y = 'total_bill', data = tips, jitter= True,hue = 'sex', dodge = True)
sns.swarmplot(x = 'day', y = 'total_bill', data = tips)
sns.factorplot(x = 'day', y = 'total_bill', kind = 'box', data = tips)

pandas & numpy 数据分析

数据集描述:

  • 数据集统计描述:
df.describe()
  • 数据集查看变量信息和缺失情况:
df.info()
profile = df.profile_repor(title = "Dataset Report")
profile.to_file(output_file = Path("./dataset_report.html"))

数据集初步处理

  • 去重复值:drop_duplicates()
df = df.drop_duplicates()
  • 空值处理:
    • pd.isna() / pd.isnull() / nnp.isnan() / Series=Series(前三nan为True,后者nan为False) - 返回布尔矩阵
    • dropna() 删除NaN
    • fillna() 设置NaN值
df.dropna() #NaN行
df.dropna(axis=1) #NaN列
dropna(how='all')
df.fillna(0)
df.fillna(method="bfill/ffill") # 向后填充/向前填充
df.fillna({"column1":1, "column2":0})
  • 换值处理:replace
df['column'].replace({11:22}) #注意inplace
  • 计数统计:
    • count():按顺序统计
    • value_counts():按排序统计
    • cumsum():样本值累计和 - 应用:按时间轴变化图
df['column'].count()
df.count() ## axis=1按列,相当于统计非NaN值
df['column'].value_counts()
df['column'].cumsum()
  • 区间映射:将xmin-xmax区间映射到a,b区间
Xmin = np.min(x_scale)
Xmax = np.max(x_scale)
#将数据映射到[2,8]区间 即a=2,b=8
a = 2
b = 8
y_scale = a + (b-a)/(Xmax-Xmin)*(x_scale-Xmin)

格式变换

  • 读取数据集时,数值型变量一开始都是str,需要转换成float
df['column'] = df['column'].astype('float')
  • str转datetime/timestamp:
df['time'] = pd.to_datetime(df['time'],format = ''%m/%d/%Y'')  # str='02/12/2015'
  • timestamp转datetime:因为timestamp不能进行计算,需要要转datetime
datetime.strptime(df.loc[:]['time'].strftime('%Y-%m-%d %H:%M:%S'),"%Y-%m-%d %H:%M:%S")

简单tricks

  • for循环进度条:tqdm
    • from tqdm import tqdm
from tqdm import tqdm
for i in tqdm(range(len(temp))):
    pass
  • 需要对每行进行遍历计算:
    • 使用apply:时间比较长而且不知道进度
    • 使用for:一般习惯使用,每行计算结果append入列表最后转为一列
res = []
for i in ..:
    ...
    res.append()
df['new_column'] = pd.Series(res)
  • 删除行删除列:
    • df.drop([...], axis=0/1, inplace=True)
  • 索引行索引列:
    • df.loc[行][列]
    • df[列][行]
  • 深拷贝:df.copy(deep=True

  • 找满足某个条件的行:

# 选出所有好评评论
querySer = df.loc[:,'star'] >= 4 
df_good = df.loc[querySer,:]
  • 统计不同的某列下的一些情况:groupby聚合
# 不同产品下各有多少条评论
# sub_df = pd.DataFrame(df_good.groupby(["product_id"],sort=True)["star"].size()).reset_index()

数据集初步分析 - 举例

  • 题目:选出获得好评最多的淘宝产品
    • 选出所有好评的评论
    • 根据产品进行聚合
    • 按好评数目降序排列
# 选出所有好评评论
querySer = df.loc[:,'star'] >= 4
df_good = df.loc[querySer,:]
# 根据产品进行聚合 - 聚合的size,就是以'product_id'索引下的条目数
# sub_df = pd.DataFrame(df_good.groupby(["product_id"],sort=True)["star"].size()).reset_index()
# 列重命名
# NameDict = {'product_id':'好评数'}
# sub_df.rename(columns = NameDict,inplace=True)
# 按好评数降序排列
# sub_df=sub_df.sort_values(by='好评数',ascending=False ,na_position='first')
# 取前5结果
sub.df.head(5)
  • 题目:1-5星评论占比与分布
    • 根据星级进行聚合
    • 计算占比
    • 分布图
#按星级进行聚合 - 因为是星级数量,所以也是size
# sub2_df = pd.DataFrame(df.groupby(["star"],sort=True)["product_id"].size()).reset_index()
#列重命名
# NameDict = {'product_id':'Review_Number'}
# sub2_df.rename(columns = NameDict,inplace=True)
# sub2_df
# a=sub2_df.loc[:,'Review_Number'].sum()
#定义新列
# aDf = pd.DataFrame()
# aDf['Percentage']=sub2_df['Review_Number']/a
# sub2_df = pd.concat([sub2_df,aDf],axis=1)
# sub2_df

# 画星级与评论数占比图
# sub2_df.plot(x='star',y=u'Percentage',kind='bar')
# plt.show()
  • 题目:写出帮助票数最多的用户/评论
sub_df = df.sort_values(by='helpful_votes',ascending=False)
  • 题目:各个产品评论数量与平均星级之间的关系
sub['num'] = pd.DataFrame(sub1.groupby(["product_id"],sort=True)["star"].size())
sub['mean'] = pd.DataFrame(sub1.groupby(["product_id"],sort=True)["star"].mean())
sub[['num','mean']].corr()

Scikit-learn 等算法模型包

LDA 文本主题模型

import nltk #nltk英文分词 / jieba中文分词
from tqdm import tqdm
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation


#从文件导入停用词表
stpwrdpath = "stop_words_english.txt"
stpwrd_dic = open(stpwrdpath, 'rb')
stpwrd_content = stpwrd_dic.read()
#将停用词表转换为list  
stpwrdlst = stpwrd_content.splitlines()
stpwrd_dic.close()
cntVector = CountVectorizer(stop_words=stpwrdlst)

# 整合所有评论分词
corpus = []
for i in tqdm(range(len(mc))):
    text = nltk.word_tokenize(mc.loc[i]['review_body'])
    corpus.append(' '.join(text))
    
# 获取词频向量
cntTf = cntVector.fit_transform(corpus)
# print(cntTf)


# 输出选取词特征
vocs = cntVector.get_feature_names()
# print('主题词袋:', len(vocs))
# print(vocs)


# 主题模型
lda = LatentDirichletAllocation(n_topics=6,
                                learning_method='online',
                                learning_offset=50.,
                                random_state=0)
docres = lda.fit_transform(cntTf)

# 类别所属概率
LDA_corpus = np.array(docres)
# print('类别所属概率:\n', LDA_corpus)
# print(len(LDA_corpus))

# 每篇文章中对每个特征词的所属概率矩阵:list长度等于分类数量
# print('主题词所属矩阵:\n', lda.components_)
# 构建一个零矩阵
LDA_corpus_one = np.zeros([LDA_corpus.shape[0]])
# 对比所属两个概率的大小,确定属于的类别:
LDA_corpus_one[LDA_corpus[:, 0] < LDA_corpus[:, 1]] = 1
# print('所属类别:', LDA_corpus_one)
 
# 打印每个单词的主题的权重值
tt_matrix = lda.components_
id = 0
for tt_m in tt_matrix:
    tt_dict = [(name, tt) for name, tt in zip(vocs, tt_m)]
    tt_dict = sorted(tt_dict, key=lambda x: x[1], reverse=True)
    # 打印每个类别前5个主题词:
    tt_dict = tt_dict[:5]
    print('主题%d:' % (id), tt_dict)
    id += 1

nlp 情感分析

from textblob import TextBlob
text = "I am happy today. I feel sad today."
blob = TextBlob(text)
#分句
blob = blob.sentences
print(blob)
 
#第一句的情感分析
first = blob.sentences[0].sentiment
print(first)
#第二句的情感分析
second = blob.sentences[1].sentiment
print(second)
#总的
all= blob.sentiment
print(all)
  • SnowNLP包 - 中文情感分析(开源)
    • 针对中文,所有算法都是自己实现的,并且自带了一些训练好的字典
from snownlp import SnowNLP
 
s = SnowNLP(u'这个东西真心赞')
s1=SnowNLP(u'还是很 设施也不错但是 和以前 比急剧下滑了 和客房 的服务极差幸好我不是很在乎')
 
s.words         # [u'这个', u'东西', u'真心',
                #  u'很', u'赞']
print(s.words)
 
s.tags          # [(u'这个', u'r'), (u'东西', u'n'),
                #  (u'真心', u'd'), (u'很', u'd'),
                #  (u'赞', u'Vg')]
print(s.tags)
p =s.sentiments    # 0.9769663402895832 positive的概率
print(p)
print(s1.sentiments)

PCA 降维

X = df.copy(deep=True)
pca = PCA(n_components=1)   # 降维维度k
newX = pca.fit_transform(X)
# print(newX)
newX = pd.DataFrame(newX)

猜你喜欢

转载自www.cnblogs.com/ymjun/p/12486879.html