【数据分析师-数据分析项目案例一】600w+条短租房数据案例分析
短租房數據案例分析
- 1 前言
- 1.1 數據集
- 1.2 數據分析思路梳理
- 2 數據分析
- 2.1 數據加載
- 2.2 數據查看
- 3 數據可視化
- 3.1 每天房屋入住率
- 3.2 房屋月份價格走勢
- 3.3 房屋星期價格特征
- 3.4 不同社區的房源數量
- 3.5 房源評分情況
- 3.6 房源價格情況
- 3.7 不同社區與房源價格的關系
- 3.8 品質房和普通房
- 3.8 配套設施和房價的關系
- 3.9 房型和房價的關系
- 3.10 配套設施必備類型
- 3.11 床位的數量和房價的關系
- 3.12 關聯關系探索
- 4 特征工程
- 5 機器學習
- 5.1 隨機森林
- 5.2 LightGBM
手動反爬蟲,禁止轉載: 原博地址 https://blog.csdn.net/lys_828/article/details/119940333(CSDN博主:Be_melting) 知識梳理不易,請尊重勞動成果,文章僅發布在CSDN網站上,在其他網站看到該博文均屬于未經作者授權的惡意爬取信息
1 前言
1.1 數據集
-
本案例中的數據來自于愛彼迎(Airbnb)網站2018-2019年度的多倫多市的真實數據。
-
數據集中包含listings數據集,約有2萬條數據,記錄著所有的房屋信息,包括價格在內的幾十項信息字段。
-
數據集中的另一個數據集是calendar,包含約650萬條的租房交易數據,擁有每一天每一所住房的入駐信息。
1.2 數據分析思路梳理
常規數據分析,數據字段載入和常見數據ETL四板斧的清洗處理
-
方法1: .isnull().sum() 檢查空值情況
-
方法2: .shape 檢查數據尺寸
-
方法3: .describe() 查看數據字段數據類型
-
方法4: .value_counts() 查看數據集合數據分布情況
數據分析師最終是要把結果以可視化的方式進行呈現,所以對于分析得到的數據要進行圖表化展示。由于本案例主要研究的目標是價格的依賴因素,所以我們采用價格和另一個因素的對比作圖來觀察。常見圖形包括:
-
圖形1: 柱狀圖,來觀察數據的分布情況
-
圖形2: 箱型圖,來觀察數據的范圍
-
圖形3: 散點矩陣圖,來觀察不同因素間的相互聯系
-
圖形4: 熱力圖,來快速篩選出高關聯度的信息因素
傳統的數據分析一般就會到此為止,但是對于探索試數據分析來說,事情才剛剛開始,為了更深入的進行數據分析,本案例開始引入機器學習模型,由于機器學習模型本質上就是數學模型,所以我們需要對數據集合進行特征工程,把數據集合變為方便模型識別的數組,本例中采用如下幾個步驟:
- 步驟1:數據的標準化
- 步驟2:缺失數據的修復
- 步驟3:字符串類數據的編碼化
- 步驟4:數據類型轉換和單位統一
對于本例中的眾多字段用簡單的線性回歸等模型已經不能很好的捕捉出數據的動態,所以我們采用一些符合機器學習模型,也就是利用一系列若關聯的特性組合出強特性的模型,在本例中我們采用兩個模型:
-
模型1 :隨機森林模型,這個模型是一個復合模型,對特征和標簽進行任意排列組合,然后通過概率方式進行建模,最大程度的降低過擬合的出現。
-
模型2 :微軟的LightGBM模型也是最近幾年非常火的復合模型,在本例中我們使用這個模型和隨機森林進行模型對比,利用R2值來選出最合適的機器學習模型。
2 數據分析
2.1 數據加載
代碼編寫是在Anaconda集成環境下的jupyter notebook上進行,首先導入數據分析所需要的模塊以及數據集
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inlinecalendar = pd.read_csv('toroto/calendar.csv.gz') print('We have', calendar.date.nunique(), 'days and', calendar.listing_id.nunique(), 'unique listings in the calendar data.')輸出結果如下:(數據包含了365天共17333份房間信息,nunique()方法是進行字段的唯一值查詢,返回字段中唯一元素的個數)
2.2 數據查看
(1)數據維度和字段信息
calendar.shapecalendar.head()輸出結果如下:(共有630w+條交易記錄,4個字段。listing_id: 房屋數據編號, date: 當前記錄時間, available: 當前房間是否沒被租賃, price 如果沒有被租賃,則顯示價格)
(2)交易的起止日期
輸出結果如下:(交易的時間范圍是在2018年10月6號至2019年10月5號,整整一年的時間)
(3)字段缺失值和字段統計
輸出結果如下:(price字段,由于房子出租后,就沒有價格顯示,只有未出租才有價格,所以該字段存在著缺失值;available字段中f (false) 代表已經被租用 , t(true) 代表可以被出租)
3 數據可視化
3.1 每天房屋入住率
讀取的數據中包含了1w多套房源,共有600w+交易記錄,涵蓋了交易的起止日期,因此可以探究每天房屋的入住情況(當天入住的數量除以總的房間數量)。具體分析的步驟如下:
#提取時間日期和房間狀態字段并賦值新變量 calendar_new = calendar[['date', 'available']] #添加一個新的字段記錄房源是夠被出租 calendar_new['busy'] = calendar_new.available.map( lambda x: 0 if x == 't' else 1) #按照時間日期進行分組求解每日入住的均值并重置索引 calendar_new = calendar_new.groupby('date')['busy'].mean().reset_index() #最后將時間日期轉化為datetime時間格式 calendar_new['date'] = pd.to_datetime(calendar_new['date']) #查看處理后的結果前五行 calendar_new.head()輸出結果如下:(date字段就是時間日期,busy字段就代表這個每天的平均入住率)
輸出結果匯總發現有個粉紅色的警示輸出提醒xxxWarning,需要了解一下pandas在進行數據處理和分析過程中會存在版本和各類模塊兼容的情況,xxxWarning是一種善意的提醒,并不是xxxError,這類提醒不會影響程序的正常運行,也可以導入模塊進行提醒忽略
導入運行后,重新執行上述分析過程,輸出結果如下:(此時就沒有粉紅色的xxxWarning提醒了)
每天房屋入住率求解完畢后,就可以進行可視化展現,由于繪制圖形的x軸部分為時間日期,且時間跨度較大,一般是采用折線圖進行繪制圖形
輸出結果如下:(通過圖中我們可以看到,10-11月是最繁忙的,然后是第二年的7-9月,由于這份數據是來自愛彼迎多倫多地區,所以可以推斷出整個短租房的入住率是在下半年會比較旺盛)
3.2 房屋月份價格走勢
此次有兩個分析技巧,由于價格部分帶有$符號和,號,所以我們需要對數據進行格式化處理,并且轉換時間字段。處理完時間字段后,使用柱狀圖進行數據分析
#先將時間日期字段轉化為datetime字段方便提取月份數據 calendar['date'] = pd.to_datetime(calendar['date']) #清洗price字段中的$符號和,號,最后轉化為浮點數方便記性計算 calendar['price'] = calendar['price'].str.replace(',', '') calendar['price'] = calendar['price'].str.replace('$', '') calendar['price'] = calendar['price'].astype(float)#按照月份進行分組匯總求解價錢的均值 mean_of_month = calendar.groupby(calendar['date'].dt.strftime('%B'),sort=False)['price'].mean() #繪制條形圖 mean_of_month.plot(kind = 'barh' , figsize = (12,7)) #添加x軸標簽 plt.xlabel('average monthly price')輸出結果如下:(上一次轉化datetime數據類型是calendar_new變量中的date字段,但是calendar變量中的date字段的數據類型還仍是字符串數據類型)
如果想要月份按照1-12月的方式進行順序輸出,可以重新指定索引。已有的索引放置在一個列表中,排好序后傳入reindex()函數中,操作如下
輸出結果如下:(圖中可以看出7月 8月和10月是平均價格最高的三個月)
3.3 房屋星期價格特征
#獲取星期的具體天數的名稱 calendar['dayofweek'] = calendar.date.dt.weekday_name #然后指定顯示的索引順序 cats = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] #提取要分析的兩個字段 price_week=calendar[['dayofweek','price']] #按照星期進行分組求解平均價錢后重新設置索引 price_week = calendar.groupby(['dayofweek']).mean().reindex(cats) #刪除不需要的字段 price_week.drop('listing_id', axis=1, inplace=True) #繪制圖形 price_week.plot() #指定軸刻度的數值及對應的標簽值 ticks = list(range(0, 7, 1)) labels = "Mon Tues Weds Thurs Fri Sat Sun".split() plt.xticks(ticks, labels)#如果不想要顯示xticks信息,可以增添plt.show() plt.show()輸出結果如下:(直接指定DataFrame繪制圖形,可能x軸的刻度和標簽信息不會全部顯示,此時可以自行指定刻度數量和對應的標簽值。短租房本身大都為了旅游而存在,所以周五周六兩天的價格都比其他時間貴出一個檔次。周末雙休,使得入駐的時間為周五周六晚兩個晚上)
3.4 不同社區的房源數量
讀取另外一個數據文件,按照每個房源社區進行分組,統計房源的數量(id字段對應著房源獨特的編號)
listings = pd.read_csv('toroto/listings.csv.gz') print('We have', listings.id.nunique(), 'listings in the listing data.')listings.groupby(by='neighbourhood_cleansed').count()[['id']].sort_values(by='id', ascending=False).head(10)輸出結果如下:(兩個字段的分組求解過程基本就是最后一行代碼的執行過程,最后還可以順帶按照字段進行排序和查看數據量)
3.5 房源評分情況
通過對review_scores_rating評分字段進行分布圖繪制,可以查看價格的分布區間范圍
#設置畫布大小尺寸 plt.figure(figsize=(12,6)) #繪制分布圖 sns.distplot(listings.review_scores_rating.dropna(), rug=True) #取消右側和上側坐標軸 sns.despine()輸出結果如下:(此處的評分標準為0-100分制,通過上述表格可以看出總體來看愛彼迎的房屋好評率非常高)
3.6 房源價格情況
前面探究了房源價格和星期之間的關聯,但是房價字段自身的信息并沒有探究,可以使用describe查看價格的情況
listings['price'] = listings['price'].str.replace(',', '') listings['price'] = listings['price'].str.replace('$', '') listings['price'] = listings['price'].astype(float)listings['price'].describe()輸出結果如下:(多倫多最昂貴的Airbnb房源價格為$ 12933 /晚(當時的價錢,現在的價錢是$ 64818 /晚),以下是房屋的鏈接:https://www.airbnb.ca/rooms/16039481?locale=en。通過鏈接可以發現之所以比平均價貴出約100倍,主要是因為這處房屋是多倫多最時尚的社區中的藝術收藏家閣樓。這些藝術收藏的價值大幅的拉高了這處房源的價格,使其和平均值有100倍的差距)
如果需要查看一下最大值或者最小值對應的記錄,可以使用argmax或者argmin如下代碼
輸出結果如下:(通過name信息可以核實,這份房源就是屬于Art Collector藝術收藏品 )
由于在數據分析中,我們需要服從正態分布的原則,對于這樣極端情況的存在,我們需要進行清理,所以把異常的價格的數據進行過濾,最終選擇的價錢是保留0-600之間的數據。具體要選取某一數值,需要看一下當前數值以上對應的房源信息數量占全體的比重,這里選取大于600以上的房源僅有200+套,占總比1w+的比例很小,而且房源免費的只有7套
去掉極端值后我們繼續觀察現在的價格分布狀態,繪制直方圖
輸出結果如下:(分箱數量bins可以自由指定,可以看出價格主要是在30-200之間)
3.7 不同社區與房源價格的關系
前面探究了不同社區和房源數量之間的關系,這里可以進一步探究不同社區和房源價錢之間的關系
plt.figure(figsize=(18,10)) sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('neighbourhood_cleansed')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='neighbourhood_cleansed', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca()ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結果如下:(最好的社區不僅房源的最高價高,而且平均價格也是所有社區中最高的,很有代表性)
3.8 品質房和普通房
在預定酒店時,瀏覽頁面中常常會推出品質房源和普通房源,在這份數據集中也是存在字段記錄這方面的信息,可以對比研究一下兩者的價錢情況
sns.boxplot(y='price', x='host_is_superhost', data=listings.loc[(listings.price <= 600) & (listings.price > 0)]) plt.show()輸出結果如下:(品質房源要比普通房源的價格要高)
3.8 配套設施和房價的關系
酒店中的軟裝特性和多少也是和房源的價錢有著密切的關系,可以依循探究不同社區的房源價格的方式進行分析,代碼基本上進行字段的修改就可以
plt.figure(figsize=(18,10)) sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('property_type')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='property_type', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca() ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結果如下:(在今后繪制此類圖形時候,代碼可以直接復制后修改對應的字段和限制的范圍即可。從這個圖中可以看到在數據處理時,如果對于極端值不進行處理,則會顯示出這樣怪異的情況,例如Aparthotel 公寓式酒店 這個關鍵詞的價格最高,但是通過boxplot我們又可以看出,其實只有一套這樣的房產,所以數據并不完整。tend(帳篷)和parking space (停車位)這樣的關鍵詞也是數量很少的,導致了數據結果顯示不準確)
根本原因就是分類中的數據值太少了,可以通過value_counts()進行查看。對于這種數值偏少的分類也可以設定一個數值作為分界點進行提取,或者根據展示需求直接提取前5、前10、前15的數據
3.9 房型和房價的關系
在租房時候,有整租有合租,還存在一些多人共用一間的情況(有點類似青年旅社),可以嘗試性探究不同的房型與房價之間的關系
sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('room_type')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='room_type', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca() ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結果如下:(整租價格最貴,其次是合租,最便宜的就是多人共用)
除了查看字段中各房型的房價信息,也可以逆向思維,根據價格來看不同房型的出租的多少,通過堆疊圖來嘗試探究
輸出結果如下:(有個明顯的分界線,就是在100前后整租房的出租的數量和其它兩種房型存在著較大的差距,100之前合租占據較大的比例,但是100以后就是整租的絕對優勢了)
3.10 配套設施必備類型
酒店中房間的配套設施,比如wifi,衛生間,開窗,24小時熱水等條件,嘗試探究出租房中必備的配套設施都有哪些,首先對amenities字段的數據進行清洗,提取里面的具體設施
listings['amenities'].head()listings.amenities = listings.amenities.str.replace("[{}]", "").str.replace('"', "")listings['amenities'].head()輸出結果如下:(需要對花括號和引號進行去除,最后就是按照逗號進行分割)
找出前20個最重要的便利設施
輸出結果如下:(Wifi 暖氣 廚房等便利設施是最重要的部分。這一部分有個很常用的功能,就是對一個字段中多項元素進行合并后進行統計計數后繪制圖像)
配套設施和房價之間的關系。理解下面的前三行代碼將會有不少的收獲
輸出結果如下:(前兩行代碼也是很實用的功能,實現字段中包含的元素的進行統計求平均的過程,結果就是可以得到元素和對應的價格均值)
3.11 床位的數量和房價的關系
listings.loc[(listings.price <= 600) & (listings.price > 0)].pivot(columns = 'beds',values = 'price').plot.hist(stacked = True,bins=100) plt.xlabel('Listing price in $')輸出結果如下:(先查看各出租房匯總不同床位出現的數量分布,主要集中在1,2,3,價錢也主要在0-200區間范圍內)
然后查看一下每種床位數量的價格關系如下
輸出結果如下:(在這份數據中驚人的發現居然沒有床的房屋價格比有2張床的房屋價格還要貴)
3.12 關聯關系探索
之前的嘗試性探索都是在指定兩個字段,然后進行兩兩分析。可以通過columns查看一下所有的字段名稱,輸出如下
兩兩單獨挑出來的字段進行分析就是基于常識,日常中都已經在大腦中潛意識認為這兩個字段可能有所關聯,如果一直使用這種方式很難挖掘出潛在的有價值信息,因此就可以借助pairplot繪制多字段的兩兩對比圖或者heatmap熱力圖探究潛在的關聯性
輸出結果如下:(只選取了部分字段)
進行熱力圖繪制,需要注意pairplot和heatmap繪制的圖形都是只需要看主對角線上下一側的圖像即可,因為生成的圖形是關于主對角線對稱
輸出結果如下:(數字越接近1,說明字段之間的相關性越強,主對角線的數值不用看都是1)
熱力圖除了查看相關性外,還有一個重要的用處就是展示三個字段之間的關系,比如上面相關性圖中可以看到價錢price字段和bathrooms床位以及bedrooms字段都有較強的關聯關系,就可以使用熱力圖將三者的關系表現出來
輸出結果如下:(該熱力圖探究的是洗漱間和臥室的數量與房子數量的關系)
那么把count()改成mean(),就變成探究洗漱間和臥室的數量與房子平均價格之間的關系
輸出結果如下:
4 特征工程
以上的內容就是傳統的數據分析要完成的內容,分析的過程依賴于數據分析師本身的經驗,而且結果都是以圖表的形式進行展現,有一個痛點就是字段較多時候,要進行分析時就需要很多很多的圖像,比如三個字段的分析,熱力圖就需要很多很多。此時就可以借助機器學習模型來探究,但是探究之前需要處理字段數據,進行特征工程。為了防止內存不足,建議在進行特征工程之前重新restart一下kernel,保證后續程序的正常運行,否則會提醒內存不足,程序報錯
import pandas as pd listings = pd.read_csv('toroto/listings.csv/listings.csv')listings['price'] = listings['price'].str.replace(',', '') listings['price'] = listings['price'].str.replace('$', '') listings['price'] = listings['price'].astype(float) listings = listings.loc[(listings.price <= 600) & (listings.price > 0)]listings.amenities = listings.amenities.str.replace("[{}]", "").str.replace('"', "")listings.amenities.head()輸出結果如下:(數據讀取之后將價格字段和設施字段還按照之前的處理方式進行預處理,注意這里程序運行后的標號,是restart之后的再次運行)
然后進行特征工程,先處理文本數據,將文本數據特征化,導入處理文本數據的模塊,進行詞向量轉化
輸出結果如下:(這一過程就是將amenities字段中所有的分類進行獨熱編碼,然后形成DataFrame數據類型)
接著處理二分類字段,將true和false的分類替換成計算機識別的1和0分類。當存在多個二分類字段時候可以進行for循環統一進行數據轉化,代碼操作如下
接著對價錢相關的字段進行缺失值填充和噪音數據的清洗,最后不要忘記將數值的字段轉化為浮點數。代碼操作如下
listings['security_deposit'] = listings['security_deposit'].fillna(value=0) listings['security_deposit'] = listings['security_deposit'].replace( '[\$,)]','', regex=True ).astype(float) listings['cleaning_fee'] = listings['cleaning_fee'].fillna(value=0) listings['cleaning_fee'] = listings['cleaning_fee'].replace( '[\$,)]','', regex=True ).astype(float)并不是讀取數據中的所有字段都有作用,比如在進行熱力圖判斷字段之間的相關關系時,有些字段之間的相關關系的都是0,這些字段就可以直接被舍棄,選取有相關關系的字段重新組成一個數據集
listings_new = listings[['host_is_superhost', 'host_identity_verified', 'host_has_profile_pic','is_location_exact', 'requires_license', 'instant_bookable', 'require_guest_profile_picture', 'require_guest_phone_verification', 'security_deposit', 'cleaning_fee', 'host_listings_count', 'host_total_listings_count', 'minimum_nights','bathrooms', 'bedrooms', 'guests_included', 'number_of_reviews','review_scores_rating', 'price']]接著就看一下這些字段中是不是還存在缺失值,上面只是進行了部分字段的處理,這里重現選取字段后仍然要進行缺失值的處理
for col in listings_new.columns[listings_new.isnull().any()]:print(col)輸出結果如下:(說明還是有字段的缺失值未進行處理)
接著處理這部分字段的缺失值,按照中位數進行填充。當字段為分類字段時,填充的方式為中位數填充,前面處理的價格字段為連續字段,使用均值進行填充
然后對分類字段進行獨熱編碼處理,并將編碼后的結果與新數據進行合并
for cat_feature in ['zipcode', 'property_type', 'room_type', 'cancellation_policy', 'neighbourhood_cleansed', 'bed_type']:listings_new = pd.concat([listings_new, pd.get_dummies(listings[cat_feature])], axis=1)此時不要忘記最開始對文本編碼的DataFrame數據,也需要進行合并,合并的方式為取交集,最終得到特征工程處理后的數據
listings_new = pd.concat([listings_new, df_amenities], axis=1, join='inner')listings_new.head()listings_new.shape輸出結果如下:(數據只剩下約1.7w,但是字段數量增加到了6000+)
5 機器學習
5.1 隨機森林
特征工程完成后,就該進行機器學習模型的創建,首先使用隨機森林回歸模型進行建模,看看最終的效果如何。模型創建的過程以及評估的流程如下
from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score from sklearn.metrics import mean_squared_error from sklearn.ensemble import RandomForestRegressory = listings_new['price'] x = listings_new.drop('price', axis =1) X_train, X_test, y_train, y_test = train_test_split(x, y, test_size = 0.25, random_state=1) rf = RandomForestRegressor(n_estimators=500, criterion='mse', random_state=3, n_jobs=-1)rf.fit(X_train, y_train)輸出結果如下:(x是沒有標簽的其余字段,y就是標簽字段,切分數據集一般就按照七三開,這里按照訓練集75%,測試集25%,隨機種子狀態設定為1。最后決策樹模型設置500棵樹,評價方式為均方差mse,隨機種子狀態為3,-1代表選擇處理器性能全開)
訓練過程會和選用的機器的性能相關,運行需要一定的時間,待運行完畢后就可以使用模型進行預測
輸出結果如下:(注意傳入predict括號中的變量,傳入X_train就對應得到訓練集計算出來的預測標簽,傳入X_test就對應著測試集計算出來的預測標簽,通過比對最終訓練集和測試集的結果可以計算出最終的預測結果)
模型的預測結果出來之后,同時也可以查看模型得到的最重要的影響因素
輸出結果如下:(影響因素一列就為傳入的字段的名稱,影響的重要性,可以通過訓練好的模型下面的feature_importances_屬性獲得)
5.2 LightGBM
只用一個模型建模獲得結果沒有對比性,無法判斷最終的預測結果是好還是壞,因此在進行預測時候往往都不是只使用一個模型進行,而是采用至少兩個模型進行對比,接下來就是使用LightGBM模型進行預測
需要先安裝LightGBM模塊,操作如下
然后從模塊中導入回歸模型,劃分數據集后構建模型
輸出結果如下:
如果顯示上放的輸出結果說明模型訓練成功,但是過程并不一定會一帆風順,可能會運行報錯如下:TypeError: Cannot interpret '<attribute 'dtype' of 'numpy.generic' objects>' as a data type,此時可以升級一下pandas和numpy的版本,比如將pandas升級到1.2.4,numpy升級到1.20.2。然后重新運行當前的notebook就可以完美解決這個問題
接著就可以使用訓練好的模型進行預測并查看模型得分,順帶可以將重要的影響因素進行可視化
輸出結果如下:(使用LightGBM模型進行預測的得分要比隨機森林模型最終的得分要高,說明此數據集較適用于LightGBM模型)
最后對比兩個模型最終給出的重要影響因素,可以發現前五個都是一樣的,只是順序上存在著不同。此外關于模型具體的講解會在后續的機器學習部分詳細介紹,這里就是明確數據分析案例的流程,知道如何進行模塊的調用創建模型和預測
總結
以上是生活随笔為你收集整理的【数据分析师-数据分析项目案例一】600w+条短租房数据案例分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt按钮禁用和激活禁用_为什么试探法只是
- 下一篇: 第二十六期:100 个网络基础知识普及,