楼主: CDA网校
4674 9

[数据挖掘理论与案例] 使用 Python 进行高级探索性数据分析 (EDA) [推广有奖]

管理员

大师

62%

还不是VIP/贵宾

-

威望
3
论坛币
31793 个
通用积分
3041.6696
学术水平
260 点
热心指数
268 点
信用等级
235 点
经验
194744 点
帖子
5102
精华
19
在线时间
3691 小时
注册时间
2019-9-13
最后登录
2024-4-28

初级热心勋章

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
对新数据集有好的感觉并不总是那么容易,而且需要时间。然而,一个好的和广泛的探索性数据分析(EDA)可以帮助你理解你的数据集,了解事物是如何连接的,以及需要做什么来正确处理你的数据集

在本文中,我们将涉及多个有用的 EDA 例程。然而,为了保持简短和紧凑,我们可能并不总是深入挖掘或解释所有含义。但实际上,在适当的 EDA 上花费足够的时间来充分理解您的数据集是任何优秀数据科学项目的关键部分。根据经验,您可能会将 80% 的时间用于数据准备和探索,而只有 20% 的时间用于实际机器学习建模。

结构、质量和内容的调查
总的来说,EDA 方法是非常迭代的。在你的调查结束时,你可能会发现一些需要你重新做所有事情的事情。这很正常!但是为了至少强加一点结构,我建议您使用以下结构进行调查:
  • 结构调查:探索数据集的一般形状,以及特征的数据类型。
  • 质量调查:了解数据集的总体质量,包括重复项、缺失值和不需要的条目。
  • 内容调查:一旦了解了数据集的结构和质量,我们就可以继续对特征值进行更深入的探索,并查看不同特征之间的关系。

但首先我们需要找到一个有趣的数据集。让我们继续从OpenML加载道路安全数据集。
  1. from sklearn.datasets import fetch_openml
复制代码
1.结构调查
在查看我们的特征矩阵X的内容之前,我们先来看看数据集的一般结构。例如,数据集有多少列和多少行?这些功能包括多少种不同的数据类型?
  1. df_X.shape
  2. >>> (363243, 67)

  3. import pandas as pd

  4. pd.value_counts(df_X.dtypes)

  5. >>> float64    61
  6. >>> object      6
  7. >>> dtype: int64
复制代码
1.1 非数值特征的结构
数据类型可以是数字和非数字。首先,让我们仔细看看非数字条目。
1_Gyhp4d0neqe5KBGmvImwuA.png

即使Sex_of_Driver是一个数字特征,它也以某种方式存储为非数字特征。这有时是由于数据记录中的一些错误造成的。在数据准备期间需要注意这些事情。

一旦解决了这个问题,我们就可以使用该.describe()函数来调查每个非数字特征有多少唯一值以及最突出的值出现的频率 - 使用代码df_X.describe(exclude="number"):

1_-ADuV2lYcNbzbn18N4hPYA.png

1.2  数值特征的结构
接下来,让我们仔细看看数值特征。更准确地说,让我们研究一下每个特征有多少个唯一值。这个过程会给我们一些关于数量的见解二进制(2 个唯一值),序数(3到~10个唯一值)和连续(超过 10 个唯一值)数据集中的特征。
  1.   include="number").nunique().sort_values()

  2. unique_values.plot.bar(logy=True, figsize=(15, 4),
  3.                        title="Unique values per feature");
复制代码
0_KU3G_PTys4YdPje0.png
1.3 结构调查结论
在第一次调查结束时,我们应该对数据集的一般结构有更好的理解。样本和特征的数量,每个特征有什么样的数据类型,有多少是二元的、有序的、分类的或连续的。对于获取此类信息的另一种方法,您还可以使用df_X.info()或df_X.describe()。

2.数据质量
在关注这些特征中存储的实际内容之前,我们先来看看数据集的总体质量。目标是对数据集有一个关于重复、缺失值和不需要的条目或记录错误等问题的全局视图。

2.1 重复数据
重复项是多次表示同一采样点的条目。例如,如果一个测量被两个不同的人注册了两次。检测这样的重复并不总是容易的,因为每个数据集可能具有唯一的标识符特征(例如,每个新样本唯一的索引号或记录时间)。所以你可能想先忽略它们。一旦你知道数据集中重复的数量,你可以简单地用.drop_duplicates().

  1. print(f"You seem to have {n_duplicates} duplicates in your database.")

  2. >>>你的数据中似乎有22个重复。

  3. columns_to_consider = df_X.drop(labels=["Accident_Index"], axis=1).columns

  4. df_X = df_X.drop_duplicates(subset=columns_to_consider)
  5. df_X.shape

  6. >>> (363221, 67)
复制代码
2.2. 缺失值
另一个值得研究的质量问题是缺失值。有一些缺失值是正常的。在这个阶段我们要识别的是数据集中的大洞,即具有大量缺失值的样本或特征。

2.2.1。每个样本
要查看每个样本的缺失值数量,我们有多种选择。最直接的方法是简单地可视化 的输出df_X.isna(),如下所示:
  1. import matplotlib.pyplot as plt

  2. plt.figure(figsize=(10, 8))
  3. plt.imshow(df_X.isna(), aspect="auto", interpolation="nearest", cmap="gray")
  4. plt.xlabel("Column Number")
  5. plt.ylabel("Sample Number");
复制代码
0_Y6ZCeQOJIRgoM11r.png
此图在 y 轴上显示 360'000 个单独样本中的每一个,在 x 轴上显示 67 个特征中的任何一个是否包含缺失值。虽然这已经是一个有用的情节,但更好的方法是使用missingno库来获得这样的情节:
  1. import missingno as msno

  2. msno.matrix(df_X, labels=True, sort="descending");
复制代码
0_y7PC85YOXYbgkSTd.png
从这两个图中我们可以看到数据集有一个巨大的漏洞,这是由一些样本丢失了超过 50% 的特征值造成的。对于这些样本,用一些替换值填充缺失值可能不是一个好主意。

因此,让我们继续删除缺失值超过 20% 的样本。该阈值的灵感来自该图右侧“数据完整性”列中的信息。
  1. df_X = df_X.dropna(thresh=df_X.shape[1] * 0.80, axis=0).reset_index(drop=True)
  2. df_X.shape

  3. >>> (319790, 67)
复制代码
2.2.2。每个功能
作为下一步,现在让我们看看每个特征的缺失值数量。为此,我们可以使用一些pandas技巧来快速识别每个特征的缺失值比率。
  1. df_X.isna().mean().sort_values().plot(
  2.     kind="bar", figsize=(15, 4),
  3.     title="Percentage of missing values per feature",
  4.     ylabel="Ratio of missing values per feature");
复制代码
0_8mI97bEou0XsJYZz.png
从这个图中我们可以看到大多数特征不包含任何缺失值。尽管如此,像2nd_Road_Class, Junction_Control,等特征Age_of_Vehicle仍然包含相当多的缺失值。因此,让我们继续删除缺失值超过 15% 的任何特征。
  1. df_X = df_X.dropna(thresh=df_X.shape[0] * 0.85, axis=1)
  2. df_X.shape

  3. >>> (319790, 60)
复制代码
2.2.3 小旁注
缺失值:删除缺失值没有严格的顺序。对于某些数据集,先处理特征然后处理样本可能会更好。此外,您决定删除每个特征或样本的缺失值的阈值因数据集而异,并且取决于您稍后打算对数据集执行的操作。


此外,到目前为止,我们只解决了数据集中的大漏洞,还没有解决如何填补较小的空白。


2.3. 不需要的条目和记录错误
数据集中质量问题的另一个来源可能是由于不需要的条目或记录错误。将此类样本与简单的异常值区分开来很重要。虽然异常值是给定特征分布不寻常的数据点,但不需要的条目或记录错误是最初不应该存在的样本。


例如,瑞士 45°C 的温度记录可能是一个异常值(如“非常不寻常”),而 90°C 的记录可能是一个错误。同样,从勃朗峰顶部记录温度可能在物理上是可能的,但很可能不应该包含在有关瑞士城市的数据集中。


当然,检测此类错误和不需要的条目并将它们与异常值区分开来并不总是直截了当,并且高度依赖于数据集。解决此问题的一种方法是对数据集进行全局查看,看看您是否可以识别出一些非常不寻常的模式。


2.3.1。数值特征
要绘制数据集的全局视图,至少对于数值特征,您可以使用 pandas 的.plot()函数并将其与以下参数结合使用:
  • lw=0:lw代表线宽。0表示我们不想显示任何线条
  • marker=".":我们告诉绘图.用作每个数据点的标记,而不是线条
  • subplots=True:subplots告诉pandas在单独的子图中绘制每个特征
  • layout=(-1, 4):此参数告诉pandas子图使用多少行和列。这-1意味着“尽可能多地”,而2意味着每行使用 2 列。
  • figsize=(15, 30), markersize=1:为确保图形足够大,我们建议图形高度与特征数量大致相同,并进行markersize相应调整。

那么这个情节是什么样的呢?
  1. df_X.plot(lw=0,
  2.           marker=".",
  3.           subplots=True,
  4.           layout=(-1, 4),
  5.           figsize=(15, 30),
  6.           markersize=1);
复制代码
0_hmre8JGDwVRWLf_5.png
该图中的每个点都是我们数据集中的一个样本(即一行),每个子图代表一个不同的特征。y 轴显示特征值,而 x 轴是样本索引。这些图可以给你很多关于数据清理和 EDA 的想法。通常,在您对该可视化的输出感到满意之前,根据需要投入尽可能多的时间是有意义的。


2.3.2. 非数字特征
在非数字特征上识别不需要的条目或记录错误有点棘手。鉴于此时,我们只想调查数据集的一般质量。因此,我们可以做的是大致了解这些非数字特征中的每一个包含多少唯一值,以及它们最常见的类别被表示的频率。为此,您可以使用:df_X.describe(exclude=["number", "datetime])

1_mkDiZqESg7a77_3Zx4W-JQ.png

有多种方法可以潜在地简化每个单独的非数字特征的质量调查。它们都不是完美的,所有这些都需要一些后续调查。但是为了展示一个这样的解决方案,我们可以做的是遍历所有非数字特征,并为每个特征绘制每个唯一值的出现次数。
  1. fig, axes = plt.subplots(ncols=1, nrows=3, figsize=(12, 8))

  2. df_non_numerical = df_X.select_dtypes(exclude=["number", "datetime"])

  3. for col, ax in zip(df_non_numerical.columns, axes.ravel()):

  4.     df_non_numerical[col].value_counts().plot(

  5.         logy=True, title=col, lw=0, marker=".", ax=ax)
  6.    
  7. plt.tight_layout();
复制代码
0_iWqPXjdYE-AOuOoO.png
我们可以看到,最常见的事故(即Accident_Index),涉及的人员超过 100 人。再深入一点(即查看这次事故的个别特征),我们可以确定这起事故发生在 2015 年 2 月 24 日 11:55 在英国卡迪夫。快速的互联网搜索显示,此条目对应于幸运的非致命事故,其中包括一辆装满养老金领取者的小巴。


应该如何处理这些相当独特的条目的决定再次留在分析数据集的人的主观手中。没有任何充分的理由来解释为什么,只是为了向您展示如何 - 让我们继续从该数据集中删除 10 个最常见的事故。
  1. accident_ids = df_non_numerical["Accident_Index"].value_counts().head(10).index

  2. df_X = df_X[~df_X["Accident_Index"].isin(accident_ids)]
  3. df_X.shape

  4. >>> (317665, 60)
复制代码
2.4. 质量调查结论
在第二次调查结束时,我们应该更好地了解我们数据集的总体质量。我们查看了重复项、缺失值和不需要的条目或记录错误。需要指出的是,我们尚未讨论如何解决数据集中剩余的缺失值或异常值。这是下一次调查的任务,但不会在本文中介绍。

3. 内容调查
到目前为止,我们只关注数据集的一般结构和质量。现在让我们更进一步,看看实际的内容。在理想情况下,此类调查将逐个特征进行。但是,一旦您拥有超过 20 到 30 个功能,这将变得非常麻烦。

出于这个原因(并根据需要使本文尽可能简短),我们将探索三种不同的方法,可以让您快速了解存储在每个功能中的内容以及它们之间的关系。

3.1。特征分布
查看每个特征的值分布是更好地理解数据内容的好方法。此外,它可以帮助指导您的 EDA,并提供有关数据清理和特征转换的大量有用信息。对数值特征执行此操作的最快方法是使用直方图。幸运的是,pandas它带有一个内置的直方图功能,可以一次绘制多个特征。


  1. df_X.hist(bins=25,figsize=(15,25),layout=(-1,5),edgcolor="black")
  2. plt.tight_layout();
复制代码
0_YMI7b7XmC4AEeWSB.png
在这个情节中可以看到很多非常有趣的事情。例如…


最常见的条目:某些功能,例如Towing_and_Articulation或Was_Vehicle_Left_Hand_Drive?主要包含仅一个类别的条目。例如,使用该.mode()函数,我们可以提取每个特征的最频繁条目的比率并将该信息可视化。
  1. most_frequent_entry = df_X.mode()

  2. df_freq = df_X.eq(most_frequent_entry.values, axis=1)

  3. df_freq = df_freq.mean().sort_values(ascending=False)

  4. display(df_freq.head())

  5. df_freq.plot.bar(figsize=(15, 4));

  6. >>> Pedestrian_Crossing-Human_Control    0.995259
  7. >>> Was_Vehicle_Left_Hand_Drive          0.990137
  8. >>> Carriageway_Hazards                  0.983646
  9. >>> Towing_and_Articulation              0.983221
  10. >>> Vehicle_Location-Restricted_Lane     0.982088
  11. >>> dtype: float64
复制代码
0_VLejD9K6wnxxu3XQ.png


偏值分布:某些数值特征也可以表现出强烈的非高斯分布。在这种情况下,您可能需要考虑如何转换这些值以使它们更正态分布。例如,对于右偏数据,您可以使用对数转换。

3.2. 特征模式
列表中的下一步是研究特定于特征的模式。这部分的目标有两个:
  • 我们能否识别功能中的特定模式,以帮助我们决定是否需要删除或修改某些条目?
  • 我们能否确定特征之间的特定关系,以帮助我们更好地理解数据集?

在深入探讨这两个问题之前,让我们仔细看看一些“随机选择”的特征。

  1. df_X[["Location_Northing_OSGR",
  2.       "1st_Road_Number",
  3.       "Journey_Purpose_of_Driver",
  4.       "Pedestrian_Crossing-Physical_Facilities"]].plot(
  5.     lw=0, marker=".", subplots=True, layout=(-1, 2),
  6.   markersize=0.1, figsize=(15, 6));
复制代码
0_u6oTeFAnQrELQ9xK.png

在顶行中,我们可以看到具有连续值的特征(例如,从数轴上看似任何数字),而在底行中,我们可以看到具有离散值的特征(例如,1、2、3 但不是 2.34)。


虽然我们可以通过多种方式探索特定模式的特征,但让我们通过决定将具有少于 25 个独特特征的特征视为离散或有序特征,将其他特征视为连续特征来简化我们的选择。

  1. cols_continuous = df_X.select_dtypes(include="number").nunique() >= 25
复制代码
3.2.1。连续特征
现在我们有了选择连续特征的方法,让我们继续使用 seabornpairplot来可视化这些特征之间的关系。需要注意的是,seaborn 的 pairplot 例程可能需要很长时间才能创建所有子图。因此,我们建议一次不要将其用于超过 10 个功能。


鉴于在我们的例子中我们只有 11 个特征,我们可以继续使用 pairplot。否则,使用类似的东西df_continuous.iloc[:, :5]可能有助于减少要绘制的特征数量。

0_GcI3NOogzN7q1JnJ.png
左上角的几个特征之间似乎有一种奇怪的关系。Location_Easting_OSGR和Longitude, 以及Location_Easting_OSGR和Latitude似乎有很强的线性关系。
  1. sns.pairplot(
  2.     df_X,
  3.           plot_kws={"s": 3, "alpha": 0.2},
  4.           hue="Police_Force",
  5.           palette="Spectral",
  6.     x_vars=["Location_Easting_OSGR", "Location_Northing_OSGR", "Longitude"],
  7.     y_vars="Latitude");
复制代码
0_BZ9fzdYV7scsai3b.png
知道这些特征包含地理信息,关于地理定位的更深入的 EDA 可能是富有成效的。然而,现在我们将把对这个配对图的进一步研究留给好奇的读者,并继续探索离散和有序特征。


3.2.2. 离散和有序特征
在离散或有序特征中寻找模式有点棘手。但也在这里,一些快速的 pandas 和 seaborn 技巧可以帮助我们大致了解我们的数据集。首先,让我们选择要调查的列。

  1. df_discrete = df_x[cols_countinous[~cols_continous].index]
复制代码
与往常一样,我们有多种方法可以研究所有这些功能。让我们尝试一个示例,将 seabornstripplot()与方便zip()的 for 循环一起用于子图。


请注意,要将值沿 y 轴方向展开,我们需要选择一个特定的(希望能提供信息)特征。虽然“正确”特征可以帮助识别一些有趣的模式,但通常任何连续特征都可以解决问题。这种图的主要兴趣是查看每个离散值包含多少样本。






二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:探索性数据分析 python 数据分析 探索性 EDA

沙发
CDA网校 学生认证  发表于 2022-4-1 10:35:33 |只看作者 |坛友微信交流群
  1. import numpy as np

  2. n_cols = 5
  3. n_elements = len(df_discrete.columns)
  4. n_rows = np.ceil(n_elements / n_cols).astype("int")

  5. y_value = df_X["Age_of_Driver"]

  6. fig, axes = plt.subplots(
  7.   ncols=n_cols, nrows=n_rows, figsize=(15, n_rows * 2.5))

  8. for col, ax in zip(df_discrete.columns, axes.ravel()):
  9.     sns.stripplot(data=df_X, x=col, y=y_value, ax=ax,
  10.                   palette="tab10", size=1, alpha=0.5)
  11. plt.tight_layout();
复制代码
0_4MH1T1ZMqZKKRrtK.png
这里要评论的东西太多了,所以我们只关注一些。特别是,让我们关注 6 个特征,其中值以某种特定模式出现,或者某些类别似乎比其他类别少得多。为了稍微改变一下,现在让我们使用该Longitude功能在 y 轴上拉伸值。
  1. selected_features = ["Vehicle_Reference_df_res", "Towing_and_Articulation",
  2.                      "Skidding_and_Overturning", "Bus_or_Coach_Passenger",
  3.                      "Pedestrian_Road_Maintenance_Worker", "Age_Band_of_Driver"]

  4. fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(16, 8))

  5. for col, ax in zip(selected_features, axes.ravel()):
  6.     sns.stripplot(data=df_X, x=col, y=df_X["Latitude"], ax=ax,
  7.                   palette="tab10", size=2, alpha=0.5)
  8. plt.tight_layout();
复制代码
0_8vDzhx5VPeSVMtsP.png
这种图已经非常丰富,但它们掩盖了同时存在大量数据点的区域。例如,在第 52 个纬度的一些地块中似乎有高密度的点。因此,让我们仔细看看适当的情节,例如violineplot(或boxenplot或boxplot就此而言)。为了更进一步,让我们也将每个可视化以Urban_or_Rural_Area.
  1. fig, axes = plt.subplots(ncols=3, nrows=2, figsize=(16, 8))

  2. for col, ax in zip(selected_features, axes.ravel()):
  3.     sns.violinplot(data=df_X, x=col, y=df_X["Latitude"], palette="Set2",
  4.                    split=True, hue="Urban_or_Rural_Area", ax=ax)
  5. plt.tight_layout();
复制代码
0_jh7Xm2HXqLsBveQ7.png
有趣的!我们可以看到,某些特征值在城市中比在农村地区更频繁(反之亦然)。此外,正如怀疑的那样,在纬度 51.5 似乎有一个高密度峰值。这很可能是由于伦敦周围人口更密集的地区(51.5074°)。

3.3. 特征关系
最后但同样重要的是,让我们来看看特征之间的关系。更准确地说,它们是如何关联的。最快的方法是通过 pandas 的.corr()功能。因此,让我们继续计算所有数值特征的特征到特征相关矩阵。


注意:根据数据集和特征类型(例如序数或连续特征),您可能希望使用该spearman方法而不是该pearson方法来计算相关性。Pearson相关评估两个连续变量之间的线性关系,而Spearman相关评估基于每个特征的排名值的单调关系。为了帮助解释这个相关矩阵,让我们使用 seaborn.heatmap()来可视化它。

  1. df_corr = df_X.corr(method="pearson")

  2. labels = np.where(np.abs(df_corr)>0.75, "S",
  3.                   np.where(np.abs(df_corr)>0.5, "M",
  4.                            np.where(np.abs(df_corr)>0.25, "W", "")))

  5. plt.figure(figsize=(15, 15))
  6. sns.heatmap(df_corr, mask=np.eye(len(df_corr)), square=True,
  7.             center=0, annot=labels, fmt='', linewidths=.5,
  8.             cmap="vlag", cbar_kws={"shrink": 0.8});
复制代码
0_jgwnvTrUdkesJz0c.png
这看起来已经很有趣了。我们可以看到一些特征之间的一些非常强的相关性。现在,如果您有兴趣实际订购所有这些不同的相关性,您可以执行以下操作:
  1. df_corr_stacked = df_corr.where(lower_triangle_mask).stack().sort_values()

  2. display(df_corr_stacked)

  3. >>> Local_Authority_(District)  Longitude                -0.509343
  4. >>>                             Location_Easting_OSGR    -0.502919
  5. >>> ...
  6. >>> Longitude                   Location_Easting_OSGR     0.999363
  7. >>> Latitude                    Location_Northing_OSGR    0.999974
  8. >>> Length: 1485, dtype: float64
复制代码
正如您所看到的,对特征相关性的调查可以提供非常丰富的信息。但是,一次查看所有内容有时可能比帮助更令人困惑。因此,仅关注具有类似功能的一个功能df_X.corrwith(df_X["Speed_limit"])可能是一种更好的方法。


此外,如果特征仍然包含大量缺失值或极端异常值,则相关性可能具有欺骗性。因此,在调查这些相关性之前,首先确保您的特征矩阵已正确准备总是很重要的。


3.4. 内容调查结论
在第三次调查结束时,我们应该对数据集中的内容有更好的理解。我们研究了价值分布、特征模式和特征相关性。但是,这些当然不是您可以执行的所有可能的内容调查和数据清理步骤。其他步骤例如是异常值检测和删除、特征工程和转换等。


正确而详细的 EDA 需要时间!这是一个非常迭代的过程,在您解决了数据集中的另一个缺陷之后,通常会让您回到起点。这个是正常的!这就是为什么我们经常说任何数据科学项目的 80% 都是数据准备和 EDA。

请注意,深入的 EDA 可能会消耗大量时间。仅仅因为某些事情看起来很有趣并不意味着您需要跟进它。始终提醒自己数据集将用于什么,并调整您的调查以支持该目标。有时也可以,只是做一个快速而肮脏的数据准备和探索。这将使您能够相当快地进入数据建模部分,并建立一些初步的基线模型并执行一些信息丰富的结果调查。


最后,如果你想了解更多关于数据分析的内容,可以点击下方地址:
https://edu.cda.cn/search?q=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90

使用道具

藤椅
Studio-R 在职认证  发表于 2022-4-1 10:40:20 |只看作者 |坛友微信交流群
数据探索是第一步

使用道具

板凳
Studio-R 在职认证  发表于 2022-4-1 10:40:42 |只看作者 |坛友微信交流群
将 80% 的时间用于数据准备和探索,而只有 20% 的时间用于实际机器学习建模。

使用道具

报纸
lxb1404 发表于 2022-4-1 12:15:08 |只看作者 |坛友微信交流群
感谢分享,支持一下~

使用道具

地板
三重虫 发表于 2022-4-1 19:59:11 |只看作者 |坛友微信交流群

使用道具

7
ZJWINBOSS 发表于 2022-4-2 07:42:05 |只看作者 |坛友微信交流群
感谢分享

使用道具

8
Edward6206 发表于 2022-4-2 10:53:49 |只看作者 |坛友微信交流群

使用道具

9
kkwei 发表于 2022-4-2 11:40:58 |只看作者 |坛友微信交流群
作者标注一下来源。

使用道具

10
楚天江南客 学生认证  发表于 2022-4-2 13:30:50 |只看作者 |坛友微信交流群
看上去很高端呀!

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-28 13:56