1. 程式人生 > >【利用python進行資料分析——基礎篇】利用Python處理和分析Excel表中資料實戰

【利用python進行資料分析——基礎篇】利用Python處理和分析Excel表中資料實戰

作為一個學習用Python進行資料分析的新手來說,通過本文來記錄分享一些我在用Python中的pandas、numpy來分析Excel表中資料的資料清洗和整理的工作,目的是熟悉numpy以及pandas基礎操作,所有操作利用Excel均可以方便實現。備註:本文中使用的是ipython完成的編輯

資料來源及結構

本文所分析的資料是通過爬蟲抓取的微博資料。選取新浪微博為資料平臺,選取我國34個省的旅遊政務官方微博為研究物件,利用爬蟲軟體Gooseeker爬取微博資訊,包括使用者名稱、粉絲數、開博日期、當月原創微博總數No、當月總微博數N、單條博文的轉發數、單條博文的評論數、條博文的點贊數。

  爬取的資料表格 test.xlsx

包括以下幾個sheet中,基本表結構見下

  

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()


# 通過上面的表格輸出可以看出,要想將sfsfweibo進行連線,需要對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_sfweiboAll_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()

 

#連線ssapbAll_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