Python數(shù)據(jù)分析案例總結 2020.3.12

近期做了四個Python數(shù)據(jù)分析的案例實踐柬采,把流程捞稿、語句和想法歸納總結罩息,做一個小小的里程碑

1.流程

明確分析目的->由數(shù)據(jù)源構建指標體系->數(shù)據(jù)清洗->數(shù)據(jù)處理及分析->結論

2.明確分析目的

-->分析問題產(chǎn)生的原因/分析業(yè)務現(xiàn)狀/通過分析對業(yè)務進行指導……
目的——是具體的、充滿定語的茫经、具有返回值的

3.由數(shù)據(jù)源構建指標體系

區(qū)分維度和指標:
維度:對應數(shù)據(jù)的每一列巷波,多個列組合也可以認為是一個維度
指標:各種統(tǒng)計值
在不同維度上得到各種指標
根據(jù)不同數(shù)據(jù)源和分析目的搭建指標體系
eg:一款付費軟件的日活/人均付費/付費渠道/付費功能/使用頻次/使用時長……

4.數(shù)據(jù)清洗

4.1導入庫

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

4.2加載文件

df = pd.read_csv('./file.csv')

4.3簡單查看數(shù)據(jù)有哪些列&類型

df.info() # 可看到缺失行在某一列上的條目數(shù)少于總數(shù),但當列數(shù)目較多時卸伞,不容易發(fā)現(xiàn)
df.head()

4.4查看數(shù)據(jù)的整體信息

df.describe()  # 整數(shù)型或浮點型數(shù)據(jù)
df.count() # 查看各列非空數(shù)據(jù)量

4.5開始數(shù)據(jù)清理

->對需要分析的維度進行清理
->對于數(shù)值型數(shù)據(jù)抹镊,可以通過describe方法輸出信息,關注最大值瞪慧、最小值髓考、平均值、行數(shù)等是否符合常理或是否滿足本次數(shù)據(jù)分析目的對數(shù)據(jù)的要求

4.5.1判斷數(shù)據(jù)是否有null值弃酌、0值等

若null值所在行數(shù)較少,刪除后不會對總體數(shù)據(jù)產(chǎn)生較大影響

df[df.salary.isnull()] 輸出salary列null值所在行的全部信息
df.drop(df[df.salary.isnull()].index, inplace = True)
df[df.salary.isnull()] # 查看是否刪除成功

若不想刪除數(shù)據(jù)儡炼,則可用聚合函數(shù)或前值/后值等替換處理妓湘,如使用平均數(shù)替換

df['salary'].replace(0,df['salary'].mean(), inplace = True)
# 注:若遇到較多0值,且要采用平均數(shù)填充乌询,可先將0值替換為np.nan榜贴,再使用列名.fillna()填充該列數(shù)據(jù)平均數(shù),這樣在計算平均數(shù)時nan所在行不會對整體平均數(shù)產(chǎn)生影響(不計入在內)
df.salary.replace(0,np.nan, inplace = True)
df.salary.fillna(df['salary'].mean(), inplace=Ture)
df['communityAverage'].fillna(df['communityAverage'].mean(), inplace=True) # 對null值妹田,也可使用fillna

df.info() 查看是否有Nan值
Nan非null值唬党,無法用 .isnull()判斷
但通過df.info()判斷存在缺失值,但又不是null時鬼佣,可查看其是否為Nan值

df['Type'].value_counts(dropna = False) #統(tǒng)計包括Nan在內的數(shù)據(jù)
data.dropna()  # 默認axis=0,how='any',刪除帶有空值的行驶拱,只要有一個空值,就刪除整行
df.dropna(how='all')            # 整行都是空值時晶衷,才會被刪除
df.dropna(how='all',axis=1))    # 整列都是空值時蓝纲,才會被刪除
df.dropna(subset=[1,2])         # 刪除指定1和2列中包含缺失值的行

4.5.2 查看是否具有重復值阴孟,展示重復的條目

如果有重復值,?般最后處理税迷,因為其他的列可能會影響到刪除那?條重復的記錄
先處理其他的列

df[df.duplicated()]  #注意這樣使用是展示各字段完全相同的條目
df.drop_duplicates('App', inplace = True)# 刪除'App'列中數(shù)據(jù)重復的行

也可根據(jù)指定部分列(待分析列)是否具有重復值

df[df[:,['employee_ID','deptno_ID','salary']].dupliacted()]
df[df.employee_ID.dupliacted()] # 單獨查看employee_ID是否具有重復值的條目

或使用行數(shù)是否相等來判斷

len(df.empolyee_ID.unique()) 與 len(df) # 是否相等永丝,相等->該列無重復
df['employee_ID'].value_counts() # 默認剔除nan值 # 是否有大于1的
df['employee_ID'].value_counts(dropna = False) # 計算包含nan值的條目
pd.unique(df['employee_ID']).size # 是否與整個數(shù)據(jù)行數(shù)相同

注意:當我們對?列取size屬性的時候,返回的是?數(shù)箭养,如果對于dataframe使?size慕嚷,返回的是行乘以列的結果,也就是總的元素數(shù)

4.5.3 刪除非所需數(shù)據(jù)

df.drop(df[df['hiretime'].dt.year<2015].index, inplace = True)
df.drop(df[df['hiretime'].dt.year>2019].index, inplace = True)
df['hiretime'].dt.year.value_counts()

4.5.4 使用分類查看是否有不合邏輯的類型

df['nationality'].value_counts()

比如該列都是用國家英文全稱來填充的毕泌,但某個結果中若出現(xiàn)數(shù)字-->不合邏輯-->是因為沒有把數(shù)字標號轉換為國家還是因為其他原因闯冷?

4.5.5 判斷字符串類型數(shù)據(jù)是否只由數(shù)字組成

df['deptno_info'].str.isnumeric() --> True or False
df['deptno_info'].str.isnumeric().sum() -->True 的條目數(shù)

數(shù)據(jù)格式轉換

    df['deptno_info'].astype('i8') #將本列轉換為數(shù)值格式

說明:
isnumeric() 方法檢測字符串是否只由數(shù)字組成。這種方法是只針對unicode對象懈词。
注:定義一個字符串為Unicode蛇耀,只需要在字符串前添加 'u' 前綴即可,如 str1 = u'Itachi';
對于 Unicode 數(shù)字坎弯、全角數(shù)字(雙字節(jié))纺涤、羅馬數(shù)字和漢字數(shù)字會返回 True ,其他會返回 False抠忘。byte數(shù)字(單字節(jié))無此方法撩炊。

print u'123'.isnumeric() # True
print u'Ⅷ'.isnumeric() # True
print u'abc123'.isnumeric() # False
print u'1.23'.isnumeric() # False

4.5.6 單位轉化 str.replace()

eg:數(shù)據(jù)單位的簡化處理
tips:轉化為數(shù)據(jù)較小單位時可以實現(xiàn)-->轉化后數(shù)據(jù)成為整數(shù)int類型,而非float

df['size'] = df['size'].replace('M','e+6') #M-->10^6 
df['size'] = df['size'].replace('k','e+3') #k-->10^3
df['size'] = df['size'].replace(',','') # 替換千位符
df['Size'].astype('f8')

使用is_convertable(v)函數(shù)定義一個方法崎脉,判斷字符串判斷是否可以轉換

def is_convertable(v): 
    try:
        float(v)
        return True
    except ValueError:
        return False

查看不能轉換的字符串分布

temp = df['size'].apply(is_convertable) -->能轉換 True
df['size'][-temp].value_counts() --> -temp 取False的
# 轉換剩下的字符串
df['size'] = df['size'].str.replace('Varies with device','0')
# 再看下是不是還有沒轉換的字符串
temp = df['size'].apply(is_convertable)
df['size'][-temp].value_counts()
# 轉換類型
# e+5這種格式使?astype直接轉為int有問題拧咳,如果想轉成int,可以先轉成f8囚灼,再轉i8
#df['size'] = df['size'].astype('f8').astype('i8')
df['size'] = df['size'].astype('i8')
# 將size為0的填充為平均數(shù)
df['size'].replace(0,df['size'].mean(), inplace = True)
df.describe()

5.數(shù)據(jù)分析

5.1樣本總數(shù)

df.count()

5.2數(shù)值類型列的常見統(tǒng)計指標

df.describe()

5.3采用不同維度和指標進行分析

① 分組 groupby
分組統(tǒng)計不同國家人員并保留兩列

nationality_data = df.groupby('nationality',as_index = False).count()[['nationality', 'ID']]
nationality_data.rename(columns={'ID':'employee_count'},inplace = True) #重命名ID列-->上述操作后ID列實際為總數(shù)

不同部門中雇員平均工資

deptno_data = df.groupby('deptno',as_index = False).mean()[['deptno','salary']

對不同分組下另一維度進行排序
eg:對App分類分組后計算其他維度平均值骆膝,并按照平均安裝量對各組降序排列

df.groupby('category').mean().sort_values('installs', ascending = False)

多列分組

# type --> free or charges
# category --> family or media or chat ..........
df.groupby(['type','category'].mean().sort_values('reviews', ascending = True/False, inplace = True/False)

② 分類計數(shù)

groupby().count()
df.groupby('nationality').count()
value_counts() 

eg:統(tǒng)計每年入職人數(shù)
年份跨度較大時灶体,有些年份可能數(shù)據(jù)較少阅签;年初或年中時,當年數(shù)據(jù)可能較少
看下每年數(shù)據(jù)的數(shù)量蝎抽,確定是否要刪除數(shù)據(jù)少的年份
將字符串轉化為日期格式政钟,方便使用內置函數(shù)

df['hiretime'] = pd.to_datetime(df['hiretime'])
df['hiretime'].dt.year.value_counts()

分類計算比例
eg:對類型和分類分組后,對其評論安裝比進行排序

g = df.groupby(['type','category']).mean()
(g['reviews'] / g['installs']).sort_values(ascending = False)

③ 按照數(shù)值排序 sort_values()

nationality_sorted_data = nationality_data.sort_values('employee_count', ascending=False)
nationality_sorted_data[nationality_sorted_data.employee_count>100] # 顯示employee_count數(shù)量大于100的數(shù)據(jù)列表
df.sort_index(inplace = True) # 按照索引排序 sort_index() 

④ 分桶 pd.cut-groupby
雇員年齡分布
生成桶樟结,5歲一個分桶 最小18歲养交,最大60歲

bins = np.arange(18,63,5)
bins_data = pd.cut(df['age'],bins)
bin_counts = df['age'].groupby(bins_data).count()
# 為圖表展示好看使用列表生成式處理index
bin_counts.index = [str(x.left) + '-' + str(x.right) for x in bin_counts.index]

⑤ 單獨取出某列
eg:取出2017年,國籍為China的所有數(shù)據(jù)

df_2017 = df[df['hiretime'].dt.year == 2017]
df_2017_China = df_2017[df_2017['nationality'] == 'China']
df_2017_China.describe()

⑥ 占比 len()/len()
統(tǒng)計salary在50~100之間的數(shù)據(jù)在所有數(shù)據(jù)中的占比

len(df[df['salary'] > 50]) & len(df[df['salary'] < 100])/len(df)

⑦ 相關性(0.5以上可以認為相關瓢宦,0.3以上可以認為是弱相關)

df.corr() # 列出二維相關性表

⑧ .head() .tail()

# 取某維度的前十名和后十名
print(product_orderby_count.head(10))
print(product_orderby_count.tail(10))

⑨ .intersection() 交集
看下銷售額和銷量最后100個的交集碎连,如果銷售額和銷量都不行,這些商品需要看看是不是要優(yōu)化或者下架

problem_productids = productid_turnover.tail(100).intersection(product_orderby_count.tail(100).index)

5.4 matplotlib查看數(shù)據(jù)效果

bin_counts.plot()
plt.show()

注意點:
1.drop刁笙、rename等方法具有inplace參數(shù)破花,具體見幫助文檔谦趣,學習初期往往忽略此參數(shù),導致數(shù)據(jù)未在原表上修改或未設置接收變量座每。運行后無輸出則說明inplace為TRUE(jupyter notebook的使用優(yōu)點)前鹅,若有輸出則應賦予接收變量或為inplace賦值;而replace沒有inplace參數(shù)峭梳,需要設置接收值
2.對多列進行操作時舰绘,留心是否需要多加一層括號,如 df.groupby(['district', 'elevator'])
3.注意到df_dis_want[(df['year'] == '2017')]判別條件這里葱椭,數(shù)據(jù)類型不同判別條件中需要考慮是否加引號''捂寿,或者可認為是數(shù)據(jù)清洗環(huán)節(jié)的疏漏

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市孵运,隨后出現(xiàn)的幾起案子秦陋,更是在濱河造成了極大的恐慌,老刑警劉巖治笨,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驳概,死亡現(xiàn)場離奇詭異,居然都是意外死亡旷赖,警方通過查閱死者的電腦和手機顺又,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來等孵,“玉大人稚照,你說我怎么就攤上這事「┟龋” “怎么了果录?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绳瘟。 經(jīng)常有香客問我雕憔,道長,這世上最難降的妖魔是什么糖声? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮分瘦,結果婚禮上蘸泻,老公的妹妹穿的比我還像新娘。我一直安慰自己嘲玫,他們只是感情好悦施,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著去团,像睡著了一般抡诞。 火紅的嫁衣襯著肌膚如雪穷蛹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天昼汗,我揣著相機與錄音肴熏,去河邊找鬼。 笑死顷窒,一個胖子當著我的面吹牛蛙吏,可吹牛的內容都是我干的。 我是一名探鬼主播鞋吉,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼鸦做,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谓着?” 一聲冷哼從身側響起泼诱,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赊锚,沒想到半個月后治筒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡改抡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年矢炼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阿纤。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡句灌,死狀恐怖,靈堂內的尸體忽然破棺而出欠拾,到底是詐尸還是另有隱情胰锌,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布藐窄,位于F島的核電站资昧,受9級特大地震影響,放射性物質發(fā)生泄漏荆忍。R本人自食惡果不足惜格带,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刹枉。 院中可真熱鬧叽唱,春花似錦、人聲如沸微宝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蟋软。三九已至镶摘,卻和暖如春嗽桩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凄敢。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工碌冶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贡未。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓种樱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親俊卤。 傳聞我的和親對象是個殘疾皇子嫩挤,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容