集群 ID 列中缺失值的问题

问题描述

我正在寻找有关如何在我的 df 中添加包含集群 ID 的列的一些帮助(用于集群数据集的算法是 DBSCAN,我尝试了以下操作

# Compute DBSCAN

db = DBSCAN(eps=1,min_samples=30,algorithm='kd_tree',n_jobs=-1).fit(X)
core_samples_mask = np.zeros_like(db.labels_,dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
np.sum(labels)
# Number of clusters in labels,ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_clusters_
n_noise_ = list(labels).count(-1)

print('Estimated number of clusters: %d' % n_clusters_)
print('Estimated number of noise points: %d' % n_noise_)
print("Silhouette Coefficient: %0.3f"
      % metrics.silhouette_score(X,labels))
    df = df.join(pd.DataFrame(labels))
    df = df.rename(columns={0:'Cluster'})
    df.head

我有一个似乎不合逻辑的问题。在聚类之前,我的数据集没有缺失值,而当我添加列(集群)时,clsuter=-1 用于噪声等,我也得到缺失值( !),所以当我尝试清理我的数据集时,我没有任何选择,除了排除 cluster=-1 和缺失值,我不想要的东西。你能帮我解决我的问题吗?

您可以在附件中找到包含问题的输出。 聚类列中大约有 3000 个缺失值,我不明白这是怎么发生的。

输入额外列之前数据集的列有 38037 行。

任何评论都会有所帮助。

谢谢

Problem with missing values

解决方法

您的 df 中的索引发生了一些问题。正如您在 Pandas join docs 中读到的,如果参数 on 没有被指定:

调用者中的列或索引级别名称以加入其他中的索引,否则加入 index-on-index。

所以,这样的事情正在发生:

labels
Out[66]: array([ 0,1,-1],dtype=int64)

# make dataframe that exactly matches labels
df = pd.DataFrame(labels,columns=['a'])

df
Out[68]: 
   a
0  0
1  0
2  0
3  1
4  1
5 -1

# change indices
df = df.set_index([pd.Index([0,3,5,7,8])])

df
Out[70]: 
   a
0  0
1  0
3  0
5  1
7  1
8 -1

df.join(pd.DataFrame(labels))
Out[71]: 
   a    0
0  0  0.0
1  0  0.0
3  0  1.0
5  1 -1.0
7  1  NaN
8 -1  NaN

如果您不需要当前索引,我建议您在 DBSCAN 之前重置索引:df.reset_index(drop=True,inplace=True)

,

代码中的这一行导致缺失值:

df = df.join(pd.DataFrame(labels))

说明:

pandas.DataFrame.join() 通过索引连接 DataFrame 对象。 “df”DataFrame 有一个 Int64Index,其值范围从 0 到 41187,但只有 38037 个条目 - 这意味着索引值不连续但包含间隙,可能是在创建数据帧之后和代码片段之前删除/过滤行执行。

包含您使用 pd.DataFrame(labels) 创建的标签的 DataFrame 将有自己的索引,值范围从 0 到 38037。如果此 DataFrame 与原始 DataFrame 连接,则生成的 DataFrame 将仅包含索引所在的行原始 DataFrame 的值和标签 DataFrame 匹配,并且由于原始 DataFrame 索引中的间隙,这仅适用于 35246 行。

最简单的解决方案是重新索引原始数据帧,使其再次包含连续的索引值:

df = df.reset_index(drop=True).join(pd.DataFrame(labels))