【利用python進行資料分析——基礎篇】利用Python處理和分析Excel表中資料實戰
作為一個學習用Python進行資料分析的新手來說,通過本文來記錄分享一些我在用Python中的pandas、numpy來分析Excel表中資料的資料清洗和整理的工作,目的是熟悉numpy以及pandas基礎操作,所有操作利用Excel均可以方便實現。備註:本文中使用的是ipython完成的編輯
資料來源及結構
本文所分析的資料是通過爬蟲抓取的微博資料。選取新浪微博為資料平臺,選取我國34個省的旅遊政務官方微博為研究物件,利用爬蟲軟體Gooseeker爬取微博資訊,包括使用者名稱、粉絲數、開博日期、當月原創微博總數No、當月總微博數N、單條博文的轉發數、單條博文的評論數、條博文的點贊數。
爬取的資料表格 test.xlsx
1、All(所有博文):所有欄位見下:其中有用欄位是‘使用者名稱、微博內容、時間、轉發數、評論數、點贊數’,共有6585條資料(備註:轉發數中的缺失值為“轉發”,評論數中的缺失值為“評論”,點贊數中的缺失值為“贊”):
2、sf(各省資訊表,此表中:省份名完整)
3、sfwibo (此表記錄的是各個微博賬號對應的省份名,省份名不完整,已知各個省份名只有前兩個字完整)
4、base_info2(爬取的微博賬戶的相關資訊)(備註:此處的“暱稱”與sfweibo中的“微博使用者名稱”等同)
本文思路:
Step1:對於All表:1)取出有用欄位。2)處理缺失值。3)資料透視
Step2:對於sf 和sfweibo 表:1)以省份名做資料連線成sf_sfweibo。2)並與All表做資料連線sf_sfweibo_All。
Step3:對於base_info表:1)與sf_sfweibo_All做資料連線 2)計算h值 3)處理資料4)計算相關性
Step4:匯出最後結果到一個Excel檔案中,完成資料處理。、
資料處理過程:
step1 :
# -*- coding=utf-8 -*-
# 匯入需要的包
from__future__import division
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy.randomimport randn
from pandasimport Series, DataFrame
from datetimeimport datetime
import xlrd, openpyxl
xlsx_file = pd.ExcelFile('test1.xlsx')
All = xlsx_file.parse('All')
1)取出有用欄位
# 刪掉表格中的無用列,保留有用列
d1 = All.drop(All.columns[:11], axis=1, inplace = False)
All = d1.drop(d1.columns[-1], axis=1, inplace = False)
# 顯示錶格前五行
All.head()
# 檢視去重未處理前表中記錄長度
len(All)
# 獲取到重複的行的行號的前20個
All[All.duplicated()==True].index[:20]
# 刪除掉重複的行,在原值上直接修改
All.drop_duplicates(inplace=True)
len(All)#通過執行結果,可以發現確實刪掉了,當前記錄條數為6159條
2)處理缺失值
# 處理缺失值,先獲取該列,將列中的"轉發”、"評論"、"贊"替換掉
# 為什麼不在讀取表格的時候直接設定呢?因為如果一開始就設定替換,會導致整張表中的"轉發”、"評論"、"贊"均會被替換掉,造成資訊損失
All[u'轉發數'][All[u'轉發數']==u'轉發'] = '0'
All[u'評論數'][All[u'評論數']==u'評論'] = '0'
All[u'點贊數'][All[u'點贊數']==u'贊'] = '0' #等價於# All[u'點贊數'].replace(u'贊','0')
All.head()
3)資料透視
All.describe()
備註:出現這個結果說明了資料型別不是數值型
#查看錶中各個列的資料型別
All.dtypes
# 為了能進行資料透視,需要將對應列的資料型別轉換成數值型
# 將DataFrame表中的某列資料進行轉換型別
All[u'轉發數']=All[u'轉發數'].astype('int64')
All[u'評論數'] = All[u'評論數'].astype('int64')
All[u'點贊數'] = All[u'點贊數'].astype('int64')
All.describe()
# 查看錶中各個列的資料型別
All.dtypes
#將預處理過的表儲存到All.xlsx中
All.to_excel('All.xlsx',index=False)
# 資料透視表
All_pivot= All.pivot_table(values=[u'轉發數',u'評論數',u'點贊數',u'微博內容'],index=[u'使用者名稱'],\
aggfunc={u'轉發數':np.sum,u'評論數':np.sum,u'點贊數':np.sum,u'微博內容':np.size})
# 給該列換名稱
All_pivot.rename(columns={u'微博內容':u'當月總微博數'},inplace=True)
All_pivot
# 將完成的透視表儲存
All_pivot.to_excel('All_pivot.xlsx')
step2
1)以省份名做資料連線成sf_sfweibo
# 讀取test1.xlsx 中的sf表
sf = xlsx_file.parse('sf')
sf.head()
#讀取test1.xlsx中的sfweibo表
sfweibo = xlsx_file.parse('sfweibo')
sfweibo.head()
# 通過上面的表格輸出可以看出,要想將sf和sfweibo進行連線,需要對sf以及sf微博中的“省份名”
# 但是,由於sfweibo 中的省份名是不完整的,已知名稱中肯定包含省份中的前兩個字,為此,需要對兩個表格切割後,進行連線
sf[u'省份前兩字'] = np.nan
for iin range(len(sf[u'省份名'])):
sf[u'省份前兩字'][i] = sf[u'省份名'][i][:2]
sfweibo[u'省份前兩字'] = np.nan
for iin range(len(sfweibo[u'省份名'])):
sfweibo[u'省份前兩字'][i] = sfweibo[u'省份名'][i][:2]
# 顯示錶格的前五行
sf.head()
# 顯示錶格的前五行
sfweibo.head()
# 儲存資料
sf.to_excel('sf.xlsx',index=False)
sfweibo.to_excel('sfweibo.xlsx',index=False)
# 連線兩表
sf_sfweibo = sf.merge(sfweibo,on=u'省份前兩字')
sf_sfweibo.head()
# 獲取連線後表格中需要的欄位名,並重新排列
sf_sfweibo1 = sf_sfweibo.iloc[:,[4,1,2]]
sf_sfweibo1.head()
# 儲存連線後的表
sf_sfweibo1.to_excel('sf_sfweibo.xlsx',index=False)
2)並與All表做資料連線sf_sfweibo_All
#連線sf_sfweibo和All_pivot兩表
sf_sfweibo = sf_sfweibo1
sf_sfweibo_All_pivot =pd.merge(sf_sfweibo,All_pivot,left_on=u'微博使用者名稱',right_on=u'使用者名稱',right_index=True)
#顯示連線後的表格的前五行
sf_sfweibo_All_pivot.head()
# 將連線後的表進行儲存
sf_sfweibo_All_pivot.to_excel('sf_sfweibo_All_pivot.xlsx',index=False)
step3:
1)與sf_sfweibo_All做資料連線
# 處理爬取的使用者的基本資訊表base_info
base = xlsx_file.parse('base_info')
base.head()
#將base表與sf_sfweibo_All_pivot進行連線
sf_sfweibo_All_pivot_base = base.merge(sf_sfweibo_All_pivot,left_on=u'暱稱',right_on=u'微博使用者名稱')
ssapb = sf_sfweibo_All_pivot_base # 名稱太長,換個名稱
ssapb.head()
# 替換某列的名字
ssapb.rename(columns={u'當月總微博數_x':u'當月總微博數'},inplace=True)
# 刪除其中的多餘列
ssapb = ssapb.drop([u'暱稱',u'當月總微博數_y'],axis=1)
# 讀取第一行的數
ssapb.iloc[0]
# 新增一列(當月原創數= 當月總微博數-當月轉發數)
ssapb[u'當月原創數'] = ssapb[u'當月總微博數']-ssapb[u'當月轉發數']
#將某列同時與某段字串連線,通過觀察網頁可以發現這是網址的特點
linkfix = "?is_ori=1&is_forward=1&is_text=1&is_pic=1&is_video=1&is_music=1&is_\
article=1&key_word=&start_time=2017-05-01&end_time=2017-05-31&is_search=1&is_searchadv=1#_0"
ssapb[u'當月博文網址'] = ssapb[u'主頁連結']+linkfix
allfix = "?profile_ftype=1&is_all=1#_0"
ssapb[u'全部博文網址'] = ssapb[u'主頁連結']+allfix
#計算出篇均轉發/點贊/評論,並新增列
ssapb[u'篇均點贊'] = ssapb[u'點贊數']/ssapb[u'當月總微博數']
ssapb[u'篇均轉發'] = ssapb[u'轉發數']/ssapb[u'當月總微博數']
ssapb[u'篇均評論'] = ssapb[u'評論數']/ssapb[u'當月總微博數']
# 讀取表中的第一行資料
ssapb.iloc[0]
# 儲存表格
ssapb.to_excel('ssapb.xlsx',index=False)
2)計算h值
# 將All表分組,獲取表格的index值
gb = All.groupby(u'使用者名稱')
gb1 = gb.size()
gbindex = gb1.index
print gbindex,gb1
#根據h指數的定義,分別計算轉發/評論/點贊h指數
# 再記錄下每個“使用者名稱的最大互動度max(轉發+評論+點贊)”
sortAllf = All.sort_values(by=[u'使用者名稱',u'轉發數'],ascending=[True,False])
sortAllc = All.sort_values(by=[u'使用者名稱',u'評論數'],ascending=[True,False])
sortAlll = All.sort_values(by=[u'使用者名稱',u'點贊數'],ascending=[True,False])
mm = (sortAllf,sortAllc,sortAlll)
# 將計算得到的結果重新儲存到一個新的DataFrame中
All_h =pd.DataFrame(np.arange(136).reshape(34,4),columns=['fh','ch','lh','max_hdd'],index=gbindex)
fh=[]
ch=[]
lh=[]
max_hdd = []
for jin range(len(mm)):
for iin gbindex:
tempdf =mm[j][mm[j][u'使用者名稱']==i]
tempdf['hdd'] = tempdf[u'轉發數']+tempdf[u'評論數']+tempdf[u'點贊數']
max_hdd.append(tempdf['hdd'].max())
tempdf['numf'] = range(len(tempdf))
if j==0:
a =len(tempdf[tempdf[u'轉發數']>=tempdf['numf']+1])
fh.append(a)
elif j==1:
b =len(tempdf[tempdf[u'評論數']>=tempdf['numf']+1])
ch.append(b)
else:
c = len(tempdf[tempdf[u'點贊數']>=tempdf['numf']+1])
lh.append(c)
All_h['fh']=fh
All_h['ch']=ch
All_h['lh']=lh
# 因為,前面的迴圈一共迴圈了三遍,使得All_h重複了3遍,因此只要獲取前34位即可
All_h['max_hdd']=max_hdd[:34]
# 插入一個綜合h指數,該指數是轉發/評論/點贊h指數三個的均值
All_h.insert(3,'HS',All_h.iloc[:,:3].mean(1))
#更改列名稱
All_h.rename(columns={'fh':u'轉發h指數','ch':u'評論h指數',\
'lh':u'點贊h指數','HS':u'綜合h指數','max_hdd':u'單篇最大互動度'},inplace=True)
All_h.head()
#連線ssapb和All_h表格
ssapb_All_h= pd.merge(ssapb, All_h, left_on=u'微博使用者名稱',right_on=u'使用者名稱',right_index=True)
#加一列原創率
ssapb_All_h[u'原創率'] = ssapb_All_h[u'當月原創數']/ssapb_All_h[u'當月總微博數']
ssapb_All_h.iloc[0]
# 存檔
ssapb_All_h.to_excel('ssapb_All_h.xlsx',index=False)
3)計算相關性
# 獲取原DataFrame中的幾列儲存到新的DataFrame中,計算綜合h指數與其他分指數之間的相關性
f1 = ssapb_All_h.loc[:,[u'綜合h指數',u'轉發h指數',u'評論h指數',u'點贊h指數']]
# 計算f1中各列資料的相關性
corr1 = f1.corr()
# 將該相關性結果存檔
corr1.to_excel('corr1.xlsx')
corr1
# 獲取原DataFrame中的幾列儲存到新的DataFrame中,計算綜合h指數與其他微博資訊之間的相關性
f2 = ssapb_All_h.loc[:,[u'綜合h指數',u'轉發數',u'評論數',u'點贊數',u'篇均轉發',u'篇均評論',u'篇均點贊']]
corr2 = f2.corr()
corr2.to_excel('corr2.xlsx')
corr2
# 獲取原DataFrame中的幾列儲存到新的DataFrame中,計算綜合h指數與其他資訊之間的相關性
f3 = ssapb_All_h.loc[:,[u'綜合h指數',u'原創率',u'粉絲數',u'微博總數',u'單篇最大互動度']]
corr3 = f3.corr()
corr3.to_excel('corr3.xlsx')
corr3
# 重新排序列
aa =ssapb_All_h.iloc[:,[8,9,10,5,15,16,0,1,2,3,4,6,14,7,11,12,13,24,20,21,22,23,17,18,19,25]]
aa.to_excel('finally.xlsx')
aa.iloc[0]
4)處理資料,處理浮點位數/轉成百分位數
# 將表中的浮點型別保留至小數點後四為
f = lambda x:'%.4f' % x
aa.ix[:,21:] = aa.ix[:,21:].applymap(f)
aa.ix[:,21:] = aa.ix[:,21:].astype('float64')
aa.iloc[0]
# 將原創率轉成百分比形式
f1 = lambda x :'%.2f%%' % (x*100)
aa[[u'原創率']]= aa[[u'原創率']].applymap(f1)
aa.to_excel('finally1.xlsx',index=False)
aa.iloc[0]
aa.sort_values(by=u'綜合h指數', ascending=False, inplace=True)
# 按照綜合h指數降序排序,新增一個排序位數
aa['rank'] =np.arange(34)+1
# 要想得到“綜合h指數/排名"的列,需要將aa['rank']和aa[u'綜合h指數']進行合併成一列,這就要求必須連線字串型別
aa['rank'] = aa['rank'].astype('string_')
aa[u'綜合h指數'] = aa[u'綜合h指數'].astype('string_')
# 連線成一列
aa[u'綜合h指數/排名'] = aa[u'綜合h指數']+'/'+ aa['rank']
aa.iloc[0]
step4
1)儲存最終資料
# 刪除掉一列rank
del aa['rank']
# 將該資料型別換回來,換成浮點型
aa[u'綜合h指數'] = aa[u'綜合h指數'].astype('float64')
aa.to_excel('finally2.xlsx',index=False)
結語:
至此,本次分析操作過程已全部結束,希望這些操作可以新手有一定的參考幫助
應親們的需求,該連結是本文的原資料表,https://github.com/clover95/DataAnalysisbyPython/tree/master/weibo