首页 > 解决方案 > 使用 pandas.read_csv 读取文件:为什么将特定列读取为字符串而不是浮点数?

问题描述

一点背景:

我正在运行二进制恒星进化代码并将进化历史存储为 gzip 压缩的 .dat 文件。我曾经有一个较小的数据集,导致大约 2000 个 .dat 文件,我在后处理期间通过附加每个文件中的列表数据来创建 3d 列表来读取这些文件。每个 .dat 文件看起来有点像这个文件

但最近我开始使用更大的数据集,进化历史文件的数量上升到约 100000 个。所以我决定将 .dat 文件压缩为 gzip 并将它们保存在一个压缩文件夹中。原因是,我在远程服务器上执行所有这些操作并且磁盘配额有限。

主要查询:

在后处理过程中,我尝试使用 pandas 从所有这些文件中读取数据作为 2d numpy 数组,这些数组堆叠形成 3d 列表(每个文件的长度不同,因此我不能使用 numpy.append 而必须使用列表) . 为了实现这一点,我使用这个:

def read_evo_history(EvoHist, zipped, z):
    ehists = []
    for i in range( len(EvoHist) ):
        if zipped == True:
            try:  
                ehists.append( pd.read_csv(z.open(EvoHist[i]), delimiter = "\t", compression='gzip', header=None).to_numpy() )
            except pd.errors.EmptyDataError:
                pass
    return ehists

outdir = "plots"
indir = "OutputFiles_allsys"


z = zipfile.ZipFile( indir+'.zip' )

EvoHist = []
for filename in z.namelist():
    if not os.path.isdir(filename):
        # read the file
        if filename[0:len("OutputFiles_allsys/EvoHist")] == "OutputFiles_allsys/EvoHist":
            EvoHist.append( filename )


zipped = True
ehists = read_evo_history(EvoHist, zipped, z)
del z                                 # Cleanup (if there's no further use of it after this)

我现在面临的问题是数据中的一个特定列被读取为字符串列表,而不是浮点数。读取文件时是否需要以某种方式转换数据类型?或者这是由于正在读取的文件中的数据类型不一致引起的?有没有办法将数据作为 numpy 浮点数组的 3d 列表获取?

PS:如果这是由输入文件不一致引起的,那么我恐怕无法再次运行我的二进制恒星进化代码,因为生成所有这些文件需要几天时间。

如果需要,我将非常乐意对此进行更多澄清。提前感谢您的时间和精力。

编辑:

我注意到只有一些文件的第 16 列被作为字符串读入。我认为这是因为那里有一些 NaN 值,但我可能错了。

图像显示了指出了 NaN 值的原始数据。显示特定列被读取为字符串的演示可以在这里。但是,另一列被读取为 float: image

标签: pythonpandas

解决方案


克服缺失值的解决方法很简单,pandas.read_csv 有一个名为的参数na_values,它允许用户传递他们想要被读取为的指定值NaNs。从pandas文档:

na_values:标量、str、list-like 或 dict,默认无

要识别为 NA/NaN 的附加字符串。如果 dict 通过,特定的每列 NA 值。默认情况下,以下值被解释为 NaN:'', ... 'NA', ...`。

Pandas 本身足够聪明,可以自动识别这些值,而无需我们明确说明。但就我而言,该文件的nan值为'nan '(是的,有一个空格!)这就是我面临这个问题的原因。代码中的一分钟更改解决了这个问题,

pd.read_csv(z.open(EvoHist[i]), delimiter = "\t", 
compression='gzip', header=None, na_values = 'nan ').to_numpy()

推荐阅读