在一个相对较大的数据集中,我们使用的建模算法(lightgbm
(在其中一个数值列(至少最初(的索引(而不是值(中检测到由NA
(而不是NaN
(引起的未知数据类型,从而引发以下错误消息:
ValueError: DataFrame.dtypes for data must be int, float or bool.
Did not expect the data types in the following fields: <col_name>
只有使用value_counts
才能找到丢失的索引值-其他方法都会丢失它。当找不到它时(但它仍然阻止了建模算法(,如何用无辜的字符串替换它?
将列向下转换为integer或float无助于消除索引中的缺失(并将其转换为允许缺失的panda扩展类型,尽管数据中没有缺失值-NA索引值的零计数(。
更多信息
具有整数值的列的数据类型为UInt32Dtype
,很可能是因为该字符串类型的索引中缺少值(pandas.NA
而不是numpy.nan
(:
test_df[col_name].value_counts(dropna=False).index
Index([1048, 1040, 1041, 1049, 1047, 1046, 1050, 1044,
1043, 1042, 1051, 1045, 1052, <NA>], dtype='object')
如您所见,NA
仅在索引中,没有与之相关的值(零计数(:
test_df[col_name].value_counts(dropna=False)
1048 123099
1040 115015
1041 114987
1049 114474
1047 114124
1046 112952
1050 112453
1044 111684
1043 110286
1042 108400
1051 106731
1045 102131
1052 42033
NaN 0
Name: <col_name>, dtype: Int64
注意仅pandas的扩展类型Int64
(而不是numpy
的int64
(,它可以容纳丢失(包括本例中的仅索引丢失(,如上所示,而dtypes
显示了另一个(32位(类型UInt32Dtype()
:
test_df[col_name].dtypes
UInt32Dtype()
什么找到NA
:
test_df[col_name].value_counts(dropna=False).index.isna().sum()
1
遗漏了什么(列表可能并不详尽(:
test_df.index.isna().sum()
0
test_df[col_name].index.isna().sum()
0
test_df.index.isnull().sum()
0
test_df[col_name].index.isnull().sum()
0
(test_df.index == np.nan).any()
False
np.sum(test_df[col_name].index == pd.NA)
0
np.sum(test_df[col_name].index == "NA")
0
(test_df.index.fillna('No label') == test_df.index).all()
True
(test_df[col_name].index.fillna('No label') == test_df[col_name].index).all()
True
(pd.Series(test_df.index).replace(np.nan, 'No label') == test_df.index).all()
True
尝试将其向下转换为float
失败:
test_df[col] = pd.to_numeric(test_df[col], errors='coerce', downcast="float")
因为它被转换为另一个新颖的仅限熊猫的扩展类型Float32
(而不是预期的numpy
的float64
(:
test_df[col].dtype
Float32Dtype()
并且CCD_ 19仍然保留在索引中:
test_df[col_name].value_counts(dropna=False).index
Index([1048.0, 1040.0, 1041.0, 1049.0, 1047.0, 1046.0, 1050.0, 1044.0,
1043.0, 1042.0, 1051.0, 1045.0, 1052.0, <NA>], dtype='object')
作为一项预防措施,我将检查管道中set_index
的所有实例,以消除重复并删除索引列中的缺失(我们在各种关键列上设置索引,以在向这个大型数据集添加新部分时提高联接性能(。
相关:
- Pandas:删除具有nan值索引的行
- NumPy或Pandas:保持数组类型为整数,同时具有NaN值
这消除了索引中持久的NA
:通过将列值传递给numpy
数组并更改其类型(此处:为int
(来重建所有列值,这显然也重建了索引:
test_df[col_name] = test_df[col_name].values.astype(int)
快速检查:
test_df[col_name].value_counts(dropna=False).index.isna().sum()
0
test_df[col_name].value_counts(dropna=False)
1048 123099
1040 115015
1041 114987
1049 114474
1047 114124
1046 112952
1050 112453
1044 111684
1043 110286
1042 108400
1051 106731
1045 102131
1052 42033
Name: <col_name>, dtype: int64