数据介绍

该项目是Data Castle上的美国King County房价预测训练赛,用到的数据取自于kaggle datasets,由@harlfoxem提供并分享,但是只选取了其中的子集,并对数据做了一些预处理使数据更加符合回归分析比赛的要求。

数据主要包括2014年5月至2015年5月美国King County的房屋销售价格以及房屋的基本信息。 数据分为训练数据和测试数据,分别保存在kc_train.csv和kc_test.csv两个文件中。 其中训练数据主要包括10000条记录,14个字段,主要字段说明如下:

  • 第一列“销售日期”("SaleDate"):2014年5月到2015年5月房屋出售时的日期
  • 第二列“销售价格”("SalePrice"):房屋交易价格,单位为美元,是目标预测值
  • 第三列“卧室数”("BedroomNum"):房屋中的卧室数目
  • 第四列“浴室数”("BathroomNum"):房屋中的浴室数目
  • 第五列“房屋面积”("LivingArea"):房屋里的生活面积
  • 第六列“停车面积”("ParkingArea"):停车坪的面积
  • 第七列“楼层数”("Floor"):房屋的楼层数
  • 第八列“房屋评分”("Rating"):King County房屋评分系统对房屋的总体评分
  • 第九列“建筑面积”("BuildingArea"):除了地下室之外的房屋建筑面积
  • 第十列“地下室面积”("BasementArea"):地下室的面积
  • 第十一列“建筑年份”("BuildingYear"):房屋建成的年份
  • 第十二列“修复年份”("RepairYear"):房屋上次修复的年份
  • 第十三列"纬度"("Latitude"):房屋所在纬度
  • 第十四列“经度”("Longitude"):房屋所在经度

测试数据主要包括3000条记录,13个字段,跟训练数据的不同是测试数据并不包括房屋销售价格,需要通过由训练数据所建立的模型以及所给的测试数据,得出测试数据相应的房屋销售价格预测值。

# 导入数据分析需要的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use('ggplot')

分别导入训练数据和测试数据,并按照数据介绍中的内容给每一列加上列名

trainDf = pd.read_csv('kc_train.csv', header = None,
names = ['SaleDate', 'SalePrice', 'BedroomNum', 'BathroomNum', 'LivingArea',
'ParkingArea', 'Floor', 'Rating', 'BuildingArea', 'BasementArea',
'BuildingYear', 'RepairYear', 'Latitude', 'Longitude'])
testDf = pd.read_csv('kc_test.csv', header = None,
names = ['SaleDate', 'BedroomNum', 'BathroomNum', 'LivingArea',
'ParkingArea', 'Floor', 'Rating', 'BuildingArea', 'BasementArea',
'BuildingYear', 'RepairYear', 'Latitude', 'Longitude'])

将训练集和测试集合并,便于对数据进行统一处理

fullDf = trainDf.append(testDf, ignore_index = True )

查看数据信息

trainDf.info()

以下为输出结果

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 14 columns):
SaleDate 10000 non-null int64
SalePrice 10000 non-null int64
BedroomNum 10000 non-null int64
BathroomNum 10000 non-null float64
LivingArea 10000 non-null int64
ParkingArea 10000 non-null int64
Floor 10000 non-null float64
Rating 10000 non-null int64
BuildingArea 10000 non-null int64
BasementArea 10000 non-null int64
BuildingYear 10000 non-null int64
RepairYear 10000 non-null int64
Latitude 10000 non-null float64
Longitude 10000 non-null float64
dtypes: float64(4), int64(10)
memory usage: 1.1 MB

训练集一共有10000条数据,且数据集中没有缺失值。可以看到数据类型全是数值型。

下面对某些数据进行处理:将销售日期转换为日期格式,并提取出年份和月份;将建筑年份分区,转化为分类变量。

# 将销售日期转换为日期格式,并提取出年份和月份
fullDf['SaleDate_year'] = pd.to_datetime(fullDf['SaleDate'], format='%Y%m%d').dt.year
fullDf['SaleDate_month'] = pd.to_datetime(fullDf['SaleDate'], format='%Y%m%d').dt.month

建筑年份从1900年到2015年,每隔15年分一组

temp_list = [i for i in range(1900, 2021)]
bins = temp_list[::15]
fullDf['BuildingYearBins'] = pd.cut(fullDf['BuildingYear'], bins=bins)

使用pandas的get_dummies方法进行one-hot编码,得到虚拟变量,添加前缀‘Year’

BuildingYearBinsDf = pd.get_dummies(fullDf['BuildingYearBins'], prefix='Year')

添加虚拟变量到数据集中

fullDf = pd.concat([fullDf, BuildingYearBinsDf], axis=1)

将建筑年份和销售日期两列删除

fullDf.drop(['BuildingYear', 'SaleDate'], axis=1, inplace=True)

查看房价的分布情况

%matplotlib notebook
trainDf['SalePrice'].hist(bins=30)

房价分布情况
# 查看房价数据的描述统计量
trainDf.SalePrice.describe()
# 以下为输出结果
count    1.000000e+04
mean     5.428749e+05
std      3.729258e+05
min      7.500000e+04
25%      3.225000e+05
50%      4.507000e+05
75%      6.450000e+05
max      6.885000e+06
Name: SalePrice, dtype: float64

可以看到房价呈现明显的右偏态分布,大部分房价位于0-100万美元的区间,但房价最高接近700万美元。从该列的描述统计量中也能发现,房价平均值大于房价中位数,表现出右偏态的特征。

由于要分析影响房价的因素,所以作出每个变量与房价之间的关系图

plotDf = fullDf.iloc[0:10000, :]    # 提取出总数据集的前10000行,即训练集的内容,用该DataFrame作图
sns.barplot(x='SaleDate_year', y='SalePrice', data=plotDf)
销售年份和房价的关系图
sns.barplot(x='SaleDate_month', y='SalePrice', data=plotDf)
销售月份和房价的关系图

2014年和2015年的房屋销售价格比较接近。每个月的房价都会有小幅波动,4、5、6、10、11月的房价处在较高水平。因此将销售月份这一变量转化为虚拟变量加入总数据集中,删除原来的销售月份列。由于销售年份与房价相关性不大,将该列也删去。

SaleDateMonthDf = pd.get_dummies(fullDf['SaleDate_month'], prefix='Month')
fullDf = pd.concat([fullDf, SaleDateMonthDf], axis=1)
fullDf.drop(['SaleDate_year', 'SaleDate_month'], axis=1, inplace=True)

sns.boxplot(x='BedroomNum', y='SalePrice', data=plotDf)

卧室数和房价的关系图
sns.boxplot(x='BathroomNum', y='SalePrice', data=plotDf)
浴室数和房价的关系图
plt.scatter(plotDf['LivingArea'], plotDf['SalePrice'])
房屋面积和房价的关系图

卧室数、浴室数为离散型变量,用箱形图;房屋面积为连续型变量,用散点图。可以看出这三者与房价均成正相关,原因也很好理解,这三个变量越大意味着房子越大,越大的房子一般都会越贵。

sns.scatterplot(x='ParkingArea', y='SalePrice', data=plotDf)
停车面积和房价的关系图
sns.boxplot(x='Floor', y='SalePrice', data=plotDf)
楼层和房价的关系图

停车面积和楼层数与房屋价格的相关性不大。从图中可以看出有很多房屋停车面积很小但是价格却很贵。而房屋楼层高可能意味着每一层的面积小,比如同样都是300平方米的房子,三层楼的占地只要100平方米,而一层楼的占地就要300平方米,很多情况下是后者的地价更贵。将这两个变量从数据集中删除。

fullDf.drop(['ParkingArea', 'Floor'], axis=1, inplace=True)

sns.boxplot(x='Rating', y='SalePrice', data=plotDf)

房屋评分和房价的关系图
sns.scatterplot(x='BuildingArea', y='SalePrice', data=plotDf)
建筑面积和房价的关系图

从图中可以看出房屋评分对房价起着相当重要的作用,基本上评分越高的房子房价也越贵。建筑面积这个变量与房屋面积类似,建筑面积越大一般都会导致房价越高。

sns.scatterplot(x='BasementArea', y='SalePrice', data=plotDf)
地下室面积和房价的关系图

可以看到地下室面积这一列数据中有很多值为0,新建一个分类变量‘HasBasement’:如果BasementArea为0则该变量为0,否则该变量为1

fullDf['HasBasement'] = 0
fullDf.at[fullDf['BasementArea'] > 0, 'HasBasement'] = 1

sns.barplot(x='BuildingYearBins', y='SalePrice', data=plotDf)

建筑年份和房价的关系图
sns.boxplot(x='RepairYear', y='SalePrice', data=plotDf)
修复年份和房价的关系图

可以看到年代很久远的房子和最近的新房子售价较高,说明建筑年份与房价有一定的相关性。年代久远的房子可能是因为其历史价值而被追捧,新房子的价格高也说明了相比旧房子人们更喜欢新建的房子。而修复年份与房价的相关性不大,很多房子没有修复,但是它们的价格差距很大,修复过的房子其价格也没有明显的规律,因此将修复年份列从数据集中删除。建筑年份已转化为虚拟变量,将建筑年份列也删除。

fullDf.drop(['RepairYear', 'BuildingYearBins'], axis=1, inplace=True)

sns.scatterplot(x='Longitude', y='Latitude', hue='SalePrice', data=plotDf)

房屋的经纬度分布

将房屋的经纬度作为坐标点画出散点图,并用颜色表示房价的高低。

利用matplotlib的Basemap模块可以在地图上根据经纬度画出点

from mpl_toolkits.basemap import Basemap

Bm = Basemap(llcrnrlon=-122.6, llcrnrlat=47.1, urcrnrlon=-121.5, urcrnrlat=47.8, resolution='h')

Basemap前四个参数是画出的经纬度的范围,最后一个参数是分辨率

Bm.drawmapboundary(fill_color='aqua') #将地图填充为蓝色
Bm.drawcoastlines() # 画出海岸线
lons = plotDf.Longitude
lats = plotDf.Latitude
x, y = Bm(lons, lats) # x、y为房屋的经纬度
Bm.scatter(x, y, marker='o', color='m') #用散点图画出每个房屋的位置

地图上房屋的分布

图中黑线是陆地和海洋的分隔线,黑线中间的部位是海洋河流,黑线外边的区域是陆地。可以看到在陆地上样本点的分布很密集。

分别选出房价最高和最低的十个点,在地图上画出它们的位置。

max_lons = plotDf.sort_values(by='SalePrice', ascending=False).Longitude[:10]
max_lats = plotDf.sort_values(by='SalePrice', ascending=False).Latitude[:10]
min_lons = plotDf.sort_values(by='SalePrice', ascending=False).Longitude[-10:]
min_lats = plotDf.sort_values(by='SalePrice', ascending=False).Latitude[-10:]

Bm1 = Basemap(llcrnrlon=-122.6, llcrnrlat=47.1, urcrnrlon=-121.5, urcrnrlat=47.8, resolution='h')
Bm1.drawmapboundary(fill_color='aqua')
Bm1.drawcoastlines()
x1, y1 = Bm1(max_lons, max_lats)
Bm1.scatter(x1, y1, marker='o', color='m')

房价前十的房屋在地图上的分布
Bm2 = Basemap(llcrnrlon=-122.6, llcrnrlat=47.1, urcrnrlon=-121.5, urcrnrlat=47.8, resolution='h')
Bm2.drawmapboundary(fill_color='aqua')
Bm2.drawcoastlines()
x2, y2 = Bm2(min_lons, min_lats)
Bm2.scatter(x2, y2, marker='o', color='m')
房价后十的房屋在地图上的分布

可以看到房价最高的十个点基本都分布在湖边,而房价最低的十个点基本都分布在内陆,这也验证了seaborn画出的散点图,房价高的点基本上都位于水畔,风景好的地方房价自然也高

特征选择

根据数据可视化的结果,与房价比较相关的几个特征为卧室数、浴室数、房屋面积、房屋评价、销售月份、建筑年份。

下面使用几种不同的方法来选取我们训练模型时需要的特征

1. 相关系数

求出每两个特征之间的相关系数,并用热力图画出。由于建筑年份和销售月份是虚拟变量,不便于单独拿出来和其他特征进行相关性比较,也会使热力图显得很乱,这里没有显示这两个特征与其他特征的相关系数。

sns.heatmap(fullDf.iloc[0:10000, [0,1,2,3,4,5,6,7,8,29]].corr(), annot = True, vmin = 0, vmax = 1)
特征之间的相关系数热力图

可以看到与房价的相关系数在0.1以上的几个特征为:卧室数、浴室数、房屋面积、建筑面积、房屋评价、地下室面积、是否有地下室。

2. 迭代特征选择

假设最后选择的特征集合为X',所有特征的集合为X,辅助特征集合为X”。

  1. 初始化X’=空集,X”=X;
  2. 对于X”中的所有特征,每次取出一个进行训练,选出一轮中得分最高的那个特征加入X',同时在X"中删除该特征;
  3. 重复第二步,直到新加入任何特征模型性能都无提升
# 引入线性回归模型和交叉检验
from sklearn import linear_model
from sklearn.model_selection import cross_val_score

lm = linear_model.LinearRegression()
df = fullDf[0:10000]
features = ['BasementArea', 'BathroomNum', 'BedroomNum', 'BuildingArea',
'Latitude', 'LivingArea', 'Longitude', 'Rating',
'Year_(1900, 1915]', 'Year_(1915, 1930]', 'Year_(1930, 1945]',
'Year_(1945, 1960]', 'Year_(1960, 1975]', 'Year_(1975, 1990]',
'Year_(1990, 2005]', 'Year_(2005, 2020]', 'Month_1', 'Month_2',
'Month_3', 'Month_4', 'Month_5', 'Month_6', 'Month_7', 'Month_8',
'Month_9', 'Month_10', 'Month_11', 'Month_12', 'HasBasement']
y = df['SalePrice']

selected_features = []
rest_features = features[:]
best_score = -1e+12
'''
交叉检验的评分标准选择'neg_mean_squared_error',即均方误差,在这里为负数,绝对值越小表示误差越小,
因此初始的best_score设置为一个绝对值很大的负值
'''
while len(rest_features)>0:
temp_best_i = ''
temp_best_score = -1e+12
for feature_i in rest_features:
temp_features = selected_features + [feature_i]
X = df[temp_features]
scores = cross_val_score(lm, X, y, cv=5, scoring='neg_mean_squared_error')
score = np.mean(scores)
if score > temp_best_score:
temp_best_score = score
temp_best_i = feature_i
print("select",temp_best_i,"acc:",temp_best_score)
if temp_best_score > best_score:
best_score = temp_best_score
selected_features += [temp_best_i]
rest_features.remove(temp_best_i)
else:
break
print("best feature set: ",selected_features,"score: ",best_score)

以下为输出结果

select LivingArea acc: -71349166475.62779
select Latitude acc: -61308736701.538574
select Rating acc: -57228772728.23087
select Longitude acc: -55217175788.554344
select Year_(1900, 1915] acc: -54266373901.291626
select Year_(1915, 1930] acc: -53265361117.21611
select Year_(1930, 1945] acc: -52314470279.37959
select Year_(1945, 1960] acc: -51128635898.9767
select BedroomNum acc: -50497821841.750175
select Year_(1960, 1975] acc: -49859660488.61521
select BathroomNum acc: -49271438161.992
select Month_4 acc: -49167258638.85094
select Month_3 acc: -49102030213.97478
select Year_(1990, 2005] acc: -49067174888.75468
select Month_12 acc: -49049580993.40038
select Year_(2005, 2020] acc: -49034235274.66737
select Year_(1975, 1990] acc: -48798669332.794945
select HasBasement acc: -48793266204.60174
select Month_7 acc: -48789312424.92695
select Month_9 acc: -48788246493.10238
select Month_10 acc: -48793653843.01216
best feature set: ['LivingArea', 'Latitude', 'Rating', 'Longitude', 'Year_(1900, 1915]', 'Year_(1915, 1930]', 'Year_(1930, 1945]', 'Year_(1945, 1960]', 'BedroomNum', 'Year_(1960, 1975]', 'BathroomNum', 'Month_4', 'Month_3', 'Year_(1990, 2005]', 'Month_12', 'Year_(2005, 2020]', 'Year_(1975, 1990]', 'HasBasement', 'Month_7', 'Month_9'] score: -48788246493.10238

迭代法选择出的特征为房屋面积、经纬度、房屋评价、建筑年份、卧室数、浴室数、销售月份、是否有地下室。

3. 随机森林特征选择法——Gini Importance

使用Gini指数表示节点的纯度,Gini指数越大纯度越低。然后计算每个节点的Gini指数 - 子节点的Gini指数之和,记为Gini decrease。最后将所有树上相同特征节点的Gini decrease加权的和记为Gini importance,该数值会在0-1之间,该数值越大即代表该节点(特征)重要性越大。

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor

X为数据集的特征,y为数据集的标签

X = fullDf[:][0:10000]
X.drop('SalePrice', axis=1, inplace=True)
y = trainDf['SalePrice']

将数据集分为训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

rfReg = RandomForestRegressor(n_estimators=50)
rfReg.fit(X_train, y_train)

combine_lists = lambda item: [item[0], item[1]]
feature_importances = list(map(combine_lists, zip(X_train.columns, rfReg.feature_importances_)))
feature_importances = pd.DataFrame(feature_importances, columns=['feature', 'importance']).sort_values(by='importance', ascending=False)
feature_importances #输出每个特征的Gini Importance,并按从大到小的顺序排序

每个特征的Gini Importance大小

根据以上三种特征选择的结果,最后选取地下室面积、浴室数、卧室数、建筑面积、经纬度、房屋面积、房屋评价、建筑年份、销售月份这几个特征,删除是否有地下室的特征。

fullDf.drop('HasBasement', axis=1, inplace=True)

算法选择

选择线性回归算法和随机森林算法,评价指标选择决定系数(R Squared)

from sklearn.metrics import r2_score

X = fullDf[:][0:10000]
X.drop('SalePrice', axis=1, inplace=True)
y = trainDf['SalePrice']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

rfReg = RandomForestRegressor(n_estimators=50)
lReg = linear_model.LinearRegression()
rfReg.fit(X_train, y_train)
lReg.fit(X_train, y_train)
print('RandomForest_R2: {}nLinearRegression_R2: {}'.format(r2_score(y_test, rfReg.predict(X_test)),
r2_score(y_test, lReg.predict(X_test))))

以下为输出结果

RandomForest_R2: 0.8329728730385538
LinearRegression_R2: 0.6319265123160838

从两种模型的决定系数可以看出,随机森林算法比线性回归算法的效果要好。因此选择随机森林算法对测试集进行预测。

房价预测

使用随机森林算法对测试集进行预测。由于选择的某些特征量纲不一样,它们的单位不在一个数量级上,可能会导致有的特征被忽略,为了消除量纲的影响,对特征进行归一化。另外,由于房屋价格的分布呈右偏态,对其取对数,使其分布接近正态分布。

from sklearn.preprocessing import MinMaxScaler

tempDf = fullDf[:]
tempDf.drop('SalePrice', axis=1, inplace=True) # tempDf为测试集和训练集中不包含房价的所有特征

minmax_scaler = MinMaxScaler()
minmax_scaler.fit(tempDf)
X = minmax_scaler.transform(tempDf)
X = pd.DataFrame(X, columns=tempDf.columns) # X为测试集和训练集归一化后的所有特征
new_X = X[:][0:10000] # new_X为训练集的所有特征
y = np.log(trainDf['SalePrice']) # y为取对数后的房价
predict_X = X[:][10000:] # predict_X为测试集的所有特征

rfReg = RandomForestRegressor(n_estimators=50)
rfReg.fit(new_X, y)
predict_y = rfReg.predict(predict_X)
predict_y = np.exp(predict_y) # 将房价由对数形式还原

predictDf = pd.DataFrame(predict_y, columns=['price'])
predictDf.to_csv('predict.csv', index = False) # 将结果转化成规定的形式输出到csv文件中

zillow房价预测相关推荐

  1. zillow房价预测比赛_Zillow房价预测:2018年美国房价将会上涨

    美国是世界上最大的国家,也是最发达的国家,这个国家的经济情况是非常不错的,而且,这个国家的各项资源也是非常不错的,也正是因为这样的现状,美国的很多现实情况都是有可能被预测的,比如房产价格,那么,zil ...

  2. zillow房价预测比赛_Zillow Prize: 百万美刀奖金的房价预测比赛

    入口:Zillow Prize Announcing Zillow Prize, a contest designed to inspire the brightest scientific mind ...

  3. zillow房价预测比赛_Zillow预测: 未来一年美国房价将大幅上涨!

    2017年,美国房产市场欣欣向荣,吸引着越来越多的海外人士前往置业投资.据Zillow房价预测显示,未来一年,美国的房产市场仍然将会非常火爆,从全美范围来看,中等房屋的价格将从现在起一年内将上涨6,2 ...

  4. zillow房价预测比赛_Kaggle竞赛 —— 房价预测 (House Prices)

    这个比赛总的情况就是给你79个特征然后根据这些预测房价 (SalePrice),这其中既有离散型也有连续性特征,而且存在大量的缺失值.不过好在比赛方提供了data_description.txt这个文 ...

  5. zillow房价预测比赛_如何看待 Kaggle 发布的 Zillow 房价预测比赛?

    这个比赛第二轮已经在上周结束了,最终大佬们拿走了百万美金,相关新闻甚至还上了时代广场大屏幕,这个比赛虽然我由于时间问题没来的及做,但是一直关注它,因为是一个比较有趣的比赛. 如下几点: 1.冠军奖金史 ...

  6. 【数据分析师-数据分析项目案例三】多因素房价预测分析案例

    多因素房价预测分析案例 1 数据来源 2 数据加载和基本的ETL 2.1 模块导入和数据加载 2.2 数据清洗 3 数据可视化 3.1 地理可视化 3.2 关系矩阵和热力图 3.3 添加衍生字段 3. ...

  7. 房价预测-paddle 实现

    课程>我的课程>百度架构师手把手教深度学习>1-4 使用飞桨重写[房价预测]模型> 1-4 使用飞桨重写[房价预测]模型 paddle初级教程第一章 第四节 王然(学生) No ...

  8. 1-2 用Python编写【房价预测】模型----paddle

    课程>我的课程>百度架构师手把手教深度学习>1-2 用Python编写[房价预测]模型> 1-2 用Python编写[房价预测]模型 paddle初级教程第一章 第二节 王然( ...

  9. 机器学习(11)线性回归(2)实战 -- 正规方程优化、梯度下降优化(波士顿房价预测)

    目录 一.波士顿房价预测(正规方程优化) API 1.获取数据集 2.划分数据集 3.标准化 4. 创建预估器,得到模型 5.模型评估(均方差评估) 代码 二.波士顿房价预测(正规方程优化) API ...

最新文章

  1. 管理数据,应用程序和主机安全-B
  2. 销售人员26个致命弱点
  3. 问题:二进制数中1的个数。
  4. C++11 - 返回类型后置
  5. 【解析】1013 Battle Over Cities (25 分)_31行代码AC
  6. oracle 时间转化函数及常见函数 .
  7. Tomcat6项目移到Tomcat7 提示 404 解决方案
  8. JVM运行参数_JVM内存模型_常用内存分析工具
  9. Codeforces 744C. Hongcow Buys a Deck of Cards(状压DP)
  10. 剑指offer java -查找旋转数组的最小数字
  11. mysql6.0_MySQL6.0安装
  12. abp(net core)+easyui+efcore实现仓储管理系统——解决方案介绍(二)
  13. 如何在html页面跳转的时候携带数据(页面跳转时参数传递问题)?
  14. 雷电模拟器 服务器无响应,雷电模拟器怎么用脚本长时间运行未响应win10
  15. bzoj 2959: 长跑 lct+并查集
  16. 企业微信没有50名员工可以扩容吗?客户数达到上限会怎样?
  17. mac原生壁纸,拿走不谢!
  18. 网络文件共享服务主流----FTP文件传输协议
  19. oracle导数时不包含某个表,EXPDP导数报ORA-00942案例
  20. 业余数学牛人的数学自学心得(转)

热门文章

  1. spring mvc -@RequestMapping注解详解
  2. 3分钟销量破千 这款笔记本告诉你大家喜欢的轻薄本什么样!
  3. Android——使用Toolbar + DrawerLayout快速实现高大上菜单侧滑(转)
  4. 黄聪:说说JSON和JSONP,也许你会豁然开朗(转)
  5. PCIe配置空间和PCI设备中的寄存器
  6. Verilog中memory数据类型
  7. jittor和pytorch生成网络对比之gan
  8. matplotlib多个饼状图
  9. LeetCode39.组合总和 JavaScript
  10. Shell合并两个文件成一个文件的两列paste,awk