这篇博客写于自己在学习算法心血来潮之时,历经一下午的鏖战,终于解决了一个很基础的问题,不禁感叹,学识往往不在于高,而在于深。

首先问题的提出是在我研究某算法时,期望将数据导入Jupyter进行分析,后来发现导入结果出现很多NaN值,大致如下:

First Seconed Third
a b v
c a NaN
b d a
a NaN NaN

首先如果从excel中导出该csv文件,会是一个DataFrame,而DataFrame是不允许随意去掉NaN的,除非你用插值或者线性拟合去替换NaN,如果要进行具体算法就必须转换为list格式。

接下来考虑list的其他函数方法,例如del,remove。

  • del函数
1
2
3
list[1,2,NaN]

del list(1) #意为去掉list中第2位的元素

首先在这里我们就可以认为del函数无法做到我们的要求了,因为我们无法精确知道每一个NaN函数的位置。

我们再尝试remove函数

  • remove函数
1
2
3
list[1,2,NaN]

list.remove(NaN) #这一步同样会报错!!

为什么这一步会报错呢?原因就在于NaN作为一个特殊的float型数据,其值不等于任何其他数(甚至不等于他自己!),也就说NaN != NaN。而remove函数只能根据具体值来锁定位置,也就是说我们可以删除1,2(因为值确定)但是NaN是没有值得,也可以认为是虚无值。

那么我们就排除掉根据定值,定位置在list中去掉该元素的方法。

既然单独找NaN找不到,我们就可以反其道而行之,不打坏的,只挑好的就行了!

例如:

1
2
3
4
5
6
7
8
import pandas as pd
import numpy as np #导入环境包

df = pd.read_csv('...') #读入数据集
print(type(df)) #结果为DataFrame

df = df.values
df = df.tolist() #这一步将DataFrame变为list,先取出实际值变为np.array,再变为list

最重要的一步:

1
2
3
for i in range(len(df)):  #将嵌套列表的每一个小表单独拎出来
df[i]=list(m for m in df[i] if m == m) #这一步将列表中的nan全部去掉,如果该元素值等于自身就留下,
不等于就删掉(就是针对NaN),这样也避免使用np.isnan。

结果如下:

1
2
3
4
5
6
[['a', 'b', 'c'],
['a', 'v', 'b'],
['b', 'z'],
['c', 'v', 'a'],
['a', 'b'],
['v']]

简直完美!