如何在不使用numpy/pandas的情况下处理CSV文件中的缺失数据?

1 投票
2 回答
3138 浏览
提问于 2025-04-18 18:31

我正在尝试从一个包含一些缺失数据的csv文件中提取数据。

Num,Sym,Element,Group,Weight,Density,Melting,Boiling,Heat,Eneg,Radius,Oxidation
1,H,Hydrogen,1,1.008,0.00008988,14.01,20.28,14.304,2.2,53,"[1,-1]"
2,He,Helium,18,4.002602,0.0001785,0.956,4.22,5.193,No_Data,31,[0]
etc

在这个例子中,缺失的值是氦的电负性,氦是一种惰性气体。我还想一次性解析这些数据(也就是说,在读取时)并将其转换为合适的数据类型,这样我就可以根据需要进行计算,使用这个函数。

import csv

def read_periodic_table(): 
    per_table = {}
    with open("element_list.csv", "r") as f:
        my_reader = csv.reader(f)
        my_reader.next() # Just skipping the header
        try:
            while True:
                tl = my_reader.next()
                per_table[tl[1]] =(int(tl[0]), tl[2], int(tl[3]), float(tl[4]),
                                   float(tl[5]), float(tl[6]), float(tl[7]),
                                   float(tl[8]), float(tl[9]), float(tl[10]),
                                   list(tl[11]))

        except StopIteration:
            return

这方法很好用,但当数据缺失时(就像上面提到的那样),我会遇到一个TypeError错误。我明白为什么会出错——你不能把"No_Data"转换成浮点数。

我看过这些问题:

这些问题可能能回答我的疑问,但我希望能避免为了一个函数而使用额外的库。

我想到的处理方法是使用一些try/except块……很多。

像这样:

num = tl[0]
name = tl[2]
group = tl[3]
try:
    weight = float(tl[4])
except TypeError:
    weight = "No_Data"
finally:
    try:
        density = float(tl[5])
    except TypeError:
        density = "No_Data"
    finally:
        try:
            ...

出于显而易见的原因,我更希望避免这种做法。有没有办法仅使用标准库来实现这个?如果答案是“没有,做起来不太容易/好”,那也没关系,我就用numpy/pandas。我只是希望能避免这样。如果有一个很好的用numpy/pandas的解决方案,并且有充分的理由说明使用额外库并不是坏事,我也会考虑。

我不想使用第三方库的原因是,包括我在内的好几个人会一起工作,之后还会有很多人使用这个程序。我不想让他们都去安装另一个库来让这个程序正常工作。

2 个回答

-2

我觉得把带有缺失值的文本数据导入到Python中,最好的方法是使用NumPy的 genfromtxt 函数。这非常简单好用。在我的情况下,缺失值用'?'表示,你应该用空字符串''来替代。

 train = np.genfromtxt(path + 'cleveland.data', float, delimiter=',',missing_values='?',filling_values=np.nan)
3

如果我真的不想用 pandas,我会这样做:

  • 为每一列指定数据类型
  • 写一个简单的转换函数,试着进行各种转换
  • 用列表推导式或生成器表达式来对每个单元格调用这个转换函数

def convert_type(cell, typ):
    try:
        return typ(cell)
    except TypeError:
        return "No_Data"

# These lines go below 'tl = my_reader.next()' in your code
col_types = [int, str, int, float, float, float, float, float, float, float, float, list]
new_row = tuple(convert_type(cell, typ) for cell, typ in zip(tl, col_types))
per_table[tl[1]] = new_row

不过,如果是我自己在做这件事,我肯定会选择用 pandas。像 Anaconda 这样的发行版是个不错的选择,它可以快速设置 Python,并且已经包含了很多有用的库,比如 pandas

撰写回答