In [1]:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
df = pd.read_csv("diamonds.csv")
df.head()
df.shape
df.info()
df.describe()
df.describe(include='O')
df.isnull().sum()
df.duplicated().sum()
df.drop_duplicates(inplace=True)
df.duplicated().sum()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 53940 entries, 0 to 53939 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Unnamed: 0 53940 non-null int64 1 carat 53940 non-null float64 2 cut 53940 non-null object 3 color 53940 non-null object 4 clarity 53940 non-null object 5 depth 53940 non-null float64 6 table 53940 non-null float64 7 price 53940 non-null int64 8 x 53940 non-null float64 9 y 53940 non-null float64 10 z 53940 non-null float64 dtypes: float64(6), int64(2), object(3) memory usage: 4.5+ MB
Out[1]:
0
In [2]:
# 选出数值变量和类别变量
numeric_features = ["carat", "depth", "table", "price", "x", "y", "z"]
categorial_features = ['cut', 'color', 'clarity']
In [3]:
# 克拉分析
sns.histplot(data=df['carat'], color='darkblue', bins='auto', kde=True)
plt.title("carat distribution", fontsize=10)
plt.show()
# 克拉特征分析:
# 克拉的最小值为0.2,最大值为5.01
# 克拉的平均值是0.7979
# 根据histplot,克拉似乎是右偏的。
In [4]:
# depth
sns.histplot(data=df['depth'], color='darkblue', bins='auto', kde=True)
plt.title("depth distribution", fontsize=10)
plt.show()
# 深度特征分析:
# 平均深度为61.74。
# 最小值是43,最大值是79。
# 从图中可以看出,深度是正态分布的。
In [5]:
# table
sns.histplot(data=df['table'], color='darkblue', bins=20, kde=True)
plt.title("table distribution", fontsize=10)
plt.show()
# 表特征分析:
# 这个表的平均值是57.45。
# 最小值是43,最大值是95。
# 根据汇总统计表,我们可以说这个特征具有右偏度。结果表明,75个分位数等于59,而最大值为95,这意味着75%的行小于分位数3。
In [7]:
# price
sns.histplot(data=df['price'], color='darkblue', bins='auto', kde=True)
plt.title("price distribution", fontsize=10)
plt.show()
# 价格特征分析:
# 最小值为326,最大值为18823。
# 平均价格是3932美元
# 根据统计表和他的图可以清楚地看出这个特征是右偏的。
In [8]:
# x
sns.histplot(data=df['x'], color='darkblue', bins='auto', kde=True)
plt.title("x distribution", fontsize=10)
plt.show()
# x特征分析:
# x的最小值为0.0,最大值为10.74。
# x的平均值是5.73。
# 根据histplot,由于平均值略大于中位数(分位数为50%),x特征的分布略有右偏。
In [9]:
# y
sns.histplot(data=df['y'], color='darkblue', bins='auto', kde=True)
plt.title("y distribution", fontsize=10)
plt.show()
# y特征分析:
# 平均是5.73。
# 最小值为0,最大值为58.90
# 根据histplot和汇总统计表,均值和中位数(Q2)几乎相等,我们可以假设y特征是正态分布的。
In [10]:
# z
sns.histplot(data=df['z'], color='darkblue', bins='auto', kde=True)
plt.title("z distribution", fontsize=10)
plt.show()
# z特征分析:
# 最小值为0,最大值为31.80。
# z的平均值是3.53
# 根据他的图和统计表,很明显这个特征是正态分布的,因为这个特征的中位数(Q2)和平均值几乎是相等的。
In [11]:
# 为每个分类列绘制饼状图
for column in categorial_features:
counts = df[column].value_counts()
sns.color_palette("bright")
plt.figure(figsize=(10, 6))
plt.pie(counts, labels=counts.index, autopct='%1.1f%%', startangle=140)
plt.title(f'Pie chart for {column}', fontdict={"color" : "darkblue", "weight" : "bold", "size" : 15})
plt.axis('equal')
plt.legend()
plt.show()
In [13]:
# 去除异常数据-钻石在所有三个维度(x, y, z)上的尺寸都为0,而仍然有价值,这是不寻常的。这种差异可能表明数据集中有错误或缺少数据。
df = df[~(df['x'] == 0) | (df['y'] == 0 | (df['z'] == 0))]
df.reset_index(drop=True, inplace=True)
def scatter(col):
plt.figure(figsize=(8, 6))
sns.set_style("darkgrid")
sns.regplot(data=df, x=col, y='price', color='blue', line_kws={"color": 'black'})
plt.title(f"{col} Vs Price", fontdict={"color" : "darkred", "weight" : "bold", "size" : 15})
plt.xlabel(col, fontdict={"color": "darkblue", "weight": "bold", "size": 10})
plt.ylabel('Price', fontdict={"color": "darkblue", "weight": "bold", "size": 10})
plt.show()
scatter('carat')
scatter('depth')
scatter('table')
scatter('x')
scatter('y')
scatter('z')
In [15]:
# 相关性分析
df[numeric_features].corr()
# """克拉:
# 克拉重量与价格(目标)之间存在很强的正相关关系(0.92),表明随着钻石克拉重量的增加,其价格有显著增加的趋势。
# 克拉重量也与尺寸x、y和z有很强的正相关,这表明越大的钻石往往有更大的克拉重量。
# 克拉重与表宽之间的相关性适中(0.18),表明这两个变量之间存在轻微的正相关关系。
# 深度:
# 深度和价格之间存在微弱的负相关(-0.01),这表明钻石的深度和价格之间几乎没有关系。
# 深度与表宽呈中等负相关(-0.30),表明随着金刚石深度的增加,其表宽有减小的趋势。
# 深度也与尺寸x、y和z呈弱负相关,这表明深度与钻石的物理尺寸之间几乎没有关系。
# 表:
# 表宽和价格之间存在弱正相关(0.13),表明这两个变量之间存在轻微的正相关关系。
# 表宽与克拉重量呈正相关(0.20),表明较大的钻石往往具有更宽的表宽。
# 表宽与尺寸x、y和z也有微弱的正相关,这表明表宽与钻石的物理尺寸之间存在轻微的正相关。
# X y z:
# 所有三个维度(x, y和z)都与克拉重量有很强的正相关(x为0.97,y为0.95,z为0.95),这表明更大的钻石在所有三个轴上都具有更大的维度。
# 尺寸(x, y和z)与价格之间存在中等到强烈的正相关关系,这表明越大的钻石往往价格越高。
# 维度x、y和z也与表宽度有弱到中度的正相关,表明这些变量之间存在轻微的正相关。"""
Out[15]:
| carat | depth | table | price | x | y | z | |
|---|---|---|---|---|---|---|---|
| carat | 1.000000 | 0.028221 | 0.181658 | 0.921610 | 0.977765 | 0.953989 | 0.955933 |
| depth | 0.028221 | 1.000000 | -0.295700 | -0.010670 | -0.025097 | -0.029141 | 0.095357 |
| table | 0.181658 | -0.295700 | 1.000000 | 0.127165 | 0.196130 | 0.184530 | 0.151599 |
| price | 0.921610 | -0.010670 | 0.127165 | 1.000000 | 0.887227 | 0.867872 | 0.863913 |
| x | 0.977765 | -0.025097 | 0.196130 | 0.887227 | 1.000000 | 0.974933 | 0.970661 |
| y | 0.953989 | -0.029141 | 0.184530 | 0.867872 | 0.974933 | 1.000000 | 0.952149 |
| z | 0.955933 | 0.095357 | 0.151599 | 0.863913 | 0.970661 | 0.952149 | 1.000000 |
In [16]:
def bivariate_barplot(col):
"""This method would compare price by each categorical feature"""
# 具有聚合指标的条形图
mean = df.groupby(col)['price'].mean()
plt.figure(figsize=(10, 6))
sns.barplot(x=mean.index, y=mean.values, palette='rainbow')
plt.title(f'Mean Price by {col}', fontdict={"color" : "darkred", "weight" : "bold", "size" : 15})
plt.xlabel(col, fontdict={"color" : "darkblue", "weight" : "bold", "size" : 10})
plt.ylabel('Mean Price', fontdict={"color" : "darkblue", "weight" : "bold", "size" : 10})
plt.show()
# mean price by cut
bivariate_barplot('cut')
# mean price by clarity
bivariate_barplot('clarity')
# mean price by color
bivariate_barplot('color')
In [17]:
def pointplot(col):
plt.figure(figsize=(10, 6))
sns.pointplot(data=df, x=col, y='price', color='purple', ci=None)
plt.title(f'Point plot of {col} vs Price', fontdict={"color" : "darkred", "weight" : "bold", "size" : 15})
plt.xlabel(col, fontdict={"color" : "darkblue", "weight" : "bold", "size" : 10})
plt.ylabel('Price', fontdict={"color" : "darkblue", "weight" : "bold", "size" : 10})
plt.legend()
plt.show()
# cut vs price
pointplot('cut')
# clarity vs price
pointplot('clarity')
# clarity vs price
pointplot('color')
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
In [ ]: