本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,如有問題請及時聯系我們以作處理,
以下文章來源于統計與資料分析實戰 ,作者嚴小樣兒
前言
分布分析法,一般是根據分析目的,將資料進行分組,研究各組別分布規律的一種分析方法,資料分組方式有兩種:等距或不等距分組,
分布分析在實際的資料分析實踐中應用非常廣泛,常見的有用戶性別分布,用戶年齡分布,用戶消費分布等等,
本文將進行如下知識點講解:
1.資料型別的修改
2.新欄位生成方法
3.資料有效性校驗
4.性別與年齡分布
分布分析
1.匯入相關庫包
import pandas as pd import matplotlib.pyplot as plt import math
2.資料處理
>>> df = pd.read_csv('UserInfo.csv') >>> df.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 1000000 entries, 0 to 999999 Data columns (total 4 columns): UserId 1000000 non-null int64 CardId 1000000 non-null int64 LoginTime 1000000 non-null object DeviceType 1000000 non-null object dtypes: int64(2), object(2) memory usage: 30.5+ MB
由于接下來我們需要做年齡分布分析,但是從源資料info()方法可知,并無年齡欄位,需要自己生成,
# 提取出生日期需要先把身份證號碼轉換成字串 >>> df['CardId'] = df['CardId'].astype('str') # 提取出生日期,并生成新欄位 >>> df['DateofBirth'] = df.CardId.apply(lambda x : x[6:10]+"-"+x[10:12]+"-"+x[12:14]) # 提取性別,待觀察性別分布 >>> df['Gender'] = df['CardId'].map(lambda x : 'Male' if int(x[-2]) % 2 else 'Female') >>> df.head()
3.計算年齡
由于資料來源于線下,并未進行資料有效性驗證,在進行年齡計算前,先針對資料進行識別,驗證,
# 提取出生日期:月和日 >>> df[['month','day']] = df['DateofBirth'].str.split('-',expand=True).loc[:,1:2] # 提取小月,查看是否有31號 >>> df_small_month = df[df['month'].isin(['02','04','06','09','11'])] # 無效資料,如圖所示 >>> df_small_month[df_small_month['day']=='31'] # 統統洗掉,均為無效資料 >>> df.drop(df_small_month[df_small_month['day']=='31'].index,inplace=True) # 同理,校驗2月 >>> df_2 = df[df['month']=='02'] # 2月份的校驗大家可以做的仔細點兒,先判斷是否潤年再進行刪減 >>> df_2[df_2['day'].isin(['29','30','31'])] # 統統洗掉 >>> df.drop(df_2[df_2['day'].isin(['29','30','31'])].index,inplace=True)
# 計算年齡 # 方法一 >>> df['Age'] = df['DateofBirth'].apply(lambda x : math.floor((pd.datetime.now() - pd.to_datetime(x)).days/365)) # 方法二 >>> df['DateofBirth'].apply(lambda x : pd.datetime.now().year - pd.to_datetime(x).year)
4.年齡分布
# 查看年齡區間,進行磁區 >>> df['Age'].max(),df['Age'].min() # (45, 18) >>> bins = [0,18,25,30,35,40,100] >>> labels = ['18歲及以下','19歲到25歲','26歲到30歲','31歲到35歲','36歲到40歲','41歲及以上'] >>> df['年齡分層'] = pd.cut(df['Age'],bins, labels = labels)
由于該資料記錄的是用戶登錄資訊,所以必定有重復資料,而Python如此強大,一個nunique()方法就可以進行去重統計了,
# 查看是否有重復值 >>> df.duplicated('UserId').sum() #47681 # 資料總條目 >>> df.count() #980954
分組后用count()方法雖然也能夠計算分布情況,但是僅限于無重復資料的情況,而Python這么無敵,提供了nunique()方法可用于計算含重復值的情況
>>> df.groupby('年齡分層')['UserId'].count() 年齡分層 18歲及以下 25262 19歲到25歲 254502 26歲到30歲 181751 31歲到35歲 181417 36歲到40歲 181589 41歲及以上 156433 Name: UserId, dtype: int64 # 通過求和,可知重復資料也被計算進去 >>> df.groupby('年齡分層')['UserId'].count().sum() # 980954 >>> df.groupby('年齡分層')['UserId'].nunique() 年齡分層 18歲及以下 24014 19歲到25歲 242199 26歲到30歲 172832 31歲到35歲 172608 36歲到40歲 172804 41歲及以上 148816 Name: UserId, dtype: int64 >>> df.groupby('年齡分層')['UserId'].nunique().sum() # 933273 = 980954(總)-47681(重復) # 計算年齡分布 >>> result = df.groupby('年齡分層')['UserId'].nunique()/df.groupby('年齡分層')['UserId'].nunique().sum() >>> result # 結果 年齡分層 18歲及以下 0.025731 19歲到25歲 0.259516 26歲到30歲 0.185189 31歲到35歲 0.184949 36歲到40歲 0.185159 41歲及以上 0.159456 Name: UserId, dtype: float64 # 格式化一下 >>> result = round(result,4)*100 >>> result.map("{:.2f}%".format) 年齡分層 18歲及以下 2.57% 19歲到25歲 25.95% 26歲到30歲 18.52% 31歲到35歲 18.49% 36歲到40歲 18.52% 41歲及以上 15.95% Name: UserId, dtype: object
通過以上結果及分布圖可以知道,19到25歲年齡段的用戶占比最高,為26%,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/220017.html
標籤:其他
