此爲以前偶爾在社區看到的優秀做業「鏈家2011-2016北京二手房成交數據分析」,在此爲了工做簡歷上的項目鞏固複習練習一次。app
環境準備函數
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline
插入數據編碼
#數據讀取
f=open(r'D:\Documents\Tencent Files\2698968530\FileRecv\日月光華鏈家成交數據\lianjia1.csv') data=pd.read_csv(f)
觀察數據spa
data.head()
合併3d
數據源一共是7個csv文件,文件名是「lianjia+1到7」,能夠使用循環語句將七個文件寫入到一個列表dataR中code
dataR=[] for i in range(1,8): f=open(r'D:\Documents\Tencent Files\2698968530\FileRecv\日月光華鏈家成交數據\lianjia{}.csv'.format(i)) data=pd.read_csv(f) dataR.append(data)
出現了error orm
UnicodeDecodeError: 'gbk' codec can't decode byte 0x97 in position 154: illegal multibyte sequence
這說明7個文件的編碼類型還不同,部分數據不能用gbk類型解碼。那咱們就須要使用try except方法,先try gbk編碼,不行就except使用咱們默認的utf-8編碼
dataY=[] for i in range(1,8): try: f=open(r'D:\Documents\Tencent Files\2698968530\FileRecv\日月光華鏈家成交數據\lianjia{}.csv'.format(i),encoding='gbk') data=pd.read_csv(f) except: f=open(r'D:\Documents\Tencent Files\2698968530\FileRecv\日月光華鏈家成交數據\lianjia{}.csv'.format(i),encoding='utf-8') data=pd.read_csv(f) dataY.append(data)
輸出列表長度看是不是7blog
len(dataY)
隨便取一個的幾行看看排序
dataY[2].tail()
數據正常顯示,說明並無問題。可是這是一個list,咱們怎麼把7個數據合併到一塊兒呢?這就須要使用到pandas包裏面的concat函數。utf-8
data=pd.concat(dataY)
對他進行描述性統計分析
data.shape
data.describe()
data.info()
data.head()
這個數據集一共有141140條數據,14個屬性值,只有「套數」和「總價」是數值類型,其餘的都是字符串類型,再取他的前3行進行觀察,發現成交單價是字符串類型,由於它寫的是xxx元/平。後期還須要再對成交單價進行數據的處理操做。
接下來咱們要對數據進行預處理了,可是首先要想到的是,數據有沒有缺失值,經過對結果是否報錯來判斷是否有缺失值
data.isnull()
...
對這些布爾值進行sum運算,能夠得出有多少缺失值
(data.isnull()).sum()
結果得出版塊(bankuai)數據缺失值爲1321,門店(mendian)缺失值爲13條,其餘的數據缺失值都是1條。
data[data.cjdanjia.isnull()]
data.dropna(how='all',inplace=True)
data.isnull().sum()
發現第57119條數據缺失是不少屬性一塊兒缺失的,使用drop_duplicates把這條數據刪除,在此以前,由於這個函數是刪除重複的下一條數據,所以須要將數據按照地區排序,將空值放在後位進行刪除,最後進行檢查。
用duplicated的subset參數指定重複的列,查找出來這些列重複的數據。而後再排序
(data.duplicated(subset=['cjdanjia','cjxiaoqu','cjlouceng','bankuai'])).sum()
data.sort_values(by='bankuai',inplace=True)
再使用drop_duplicates函數,就能夠去掉這些重複值了,同時能保留板塊的有效信息
data.drop_duplicates(subset=['cjdanjia','cjxiaoqu','cjlouceng'],inplace=True)
數據類型轉換,異常值處理,數據離散化
咱們想對成交單價進行分析,這列數據很是重要。可是它是字符串形式,咱們要把單價和'元/平'分開來。首先咱們先看一下是否是全部數據包含了'元/平'。波浪號~放在語句前面表示否認。
data.head()
(~data.cjdanjia.str.contains('元/平')).sum()
得出結果爲0。 得出不包含'元/平'的數據數量爲0 ,則就是都有'元/平'。那咱們定義一個lambda x函數,把這裏數據進行轉換,把'元/平'替換爲空字符串
data.cjdanjia.map(lambda x:round(float(x.replace('元/平',''))/10000,2))
把元/平變成了空字符串,那麼數據就只留下了單價數值。而後咱們把這個單價從字符串object類型,astype變成float類型,便於後面的計算。而後除以10000,用round函數保留2位小數點。這樣得出來的結果就是3.45萬,5.31萬的類型。
當作交單價的最大最小值
data.cjdanjia.min()
data.cjdanjia.max()
發現最小值爲0,去掉0的數據,再看最小值
data=data[data.cjdanjia>0]
data.cjdanjia.min()
此時最小值爲0.01,仍是不正常,爲了處理這樣的異常值,咱們須要設置一個範圍,好比5000元一平,往上的數據纔算有效數據
data=data[data.cjdanjia>0.5]
data.cjdanjia.min()
此時最小值爲0..51,單價數據是咱們想要的數據類型了,咱們想把這些數據進行離散化,分紅多個區間,當作交單價的分佈,這個時候就須要使用到bins和cut函數
bins=[0,1,2,3,4,5,7,9,11,13,15]
pd.cut(data.cjdanjia,bins)
再對這份數據進行value_counts,看看落在各個區間上的數據都有多少
pd.cut(data.cjdanjia,bins).value_counts()
畫出點圖
pd.cut(data.cjdanjia,bins).value_counts().plot()
而後直接畫個柱狀圖看看。rot是讓x軸標籤傾斜20度,否則會擠在一塊兒。
pd.cut(data.cjdanjia,bins).value_counts().plot.bar(rot=20)
也能夠畫出餅圖
pd.cut(data.cjdanjia,bins).value_counts().plot.pie(figsize=(8,8))
字符串的處理
首先,咱們看看是否是全部數據都包含這三個數據,也就是用/分開以後,是否是都是三個數據,以避免套用函數報錯
(data.cjlouceng.str.split('/').map(len)!=3).sum()
0
data.cjlouceng
能夠把朝向這個數據單獨取出來以後,單獨給原表增長一列'chaoxiang
data.cjlouceng.map(lambda x:x.split('/')[0])
data['chaoxiang']=data.cjlouceng.map(lambda x:x.split('/')[0])
樓層這列也這樣處理
data['louceng']=data.cjlouceng.map(lambda x:x.split('/')[1])
data
對樓層取unique,能夠看出還有未知這個數據,咱們把未知這類數據去掉。(原始數據還有空字符串' ',以前處理的時候已經查找出來了,可是沒有記錄在此)
data.louceng.unique()
還有未知和空字符串的部分數據也須要處理
data[data.louceng=='']
data[data.louceng=='未知']
data=data[(data.louceng!='未知')&(data.louceng!='')]
data
pd.get_dummies(data.louceng)
而後咱們能夠使用get_dummies對樓層的這幾個類別進行one-hot處理,這樣就能很是方便離散化處理,而後得出各個類別的counts。
而後再使用join函數,把這個結果直接插入到原表後面去
data.join(pd.get_dummies(data.louceng))
再進行sum,得出各個類別的數量
pd.get_dummies(data.louceng).sum()
他的柱形圖
pd.get_dummies(data.louceng).sum().plot.bar()
把數據導出成csv文件。爲了防止index變成亂碼,添加用utf_8_sig編碼的參數。
(pd.get_dummies(data.louceng).sum()).to_csv('loucengfenbu3.csv',encoding='utf_8_sig')
分組運算、布爾過濾和數據透視
首先,對於成交時間進行處理,僅取出中間的年
data['cjshijian']=data.cjshijian.map(lambda x:x.split(':')[1])
先進行分隔,取後面的時間,再再按照-進行分隔,取年份
data['year']=data.cjshijian.map(lambda x:x.split('-')[0])
data.groupby(['year','xingming'])['xingming'].value_counts()
分析每年的經紀人數量。按照年份,經紀人姓名分組
data.groupby(['year','xingming'])['xingming'].count()
研究成交總價大於1億的經紀人的工做年限。咱們能夠先分組,而後再sum,查出大於1億的數據
data_group=data.groupby(['xingming','congyenianxian'])['cjzongjia'].sum()
data_group[data_group>10000]
等等也能夠研究其餘的問題。