Python 读取缺少单元格的ascii数据行?

Python 读取缺少单元格的ascii数据行?,python,python-3.x,csv,numpy,ascii,Python,Python 3.x,Csv,Numpy,Ascii,我有一个ascii文件,其中有3行数据,如下所示: Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37 SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30 Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37

我有一个ascii文件,其中有3行数据,如下所示:

Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30
Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30
Timestamp: 00:49:14                                     SATID 14 VAL1 22 VAL2 265 SIGNAL 30
raw_data = ["Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30",
            "Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30",
            "Timestamp: 00:49:14                                     SATID 14 VAL1 22 VAL2 265 SIGNAL 30"]

output = []
for line in raw_data:
    if 'SATID' in line:  #making sure it is not an empty line
        timestamp = line.split(' SATID ')[0].split('Timestamp: ')[1].rstrip(' ')
        data = line.split(' SATID ')[1:]
        for record in data:
            if 'VAL1' in record:  #making sure it is not an empty record
                satid = record.split(' VAL1 ')[0]
                val1 = record.split(' VAL1 ')[1].split(' VAL2 ')[0]
                val2 = record.split(' VAL2 ')[1].split(' SIGNAL ')[0]
                signal = record.split(' SIGNAL ')[1].rstrip(' ')
                output.append({'Timestamp':timestamp,
                               'SATID':satid,
                               'VAL1':val1,
                               'VAL2':val2,
                               'SIGNAL':signal})


# output is now a list of dictionaries
for d in output:
    print(d)
(原始格式请参见图片)。但是,当我尝试将其读入Python时,会出现以下错误:

time,sat1,sat2,sat3,sat4 = np.loadtxt("test1.asc", usecols=(1,9,17,25,33), unpack=True, converters = {1: strpdate2num("%H:%M:%S")})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/npyio.py", line 839, in loadtxt
vals = [vals[i] for i in usecols]
IndexError: list index out of range
time,sat1,sat2,sat3,sat4=np.loadtxt(“test1.asc”,usecols=(1,9,17,25,33),unpack=True,converters={1:strpdate2num(“%H:%M:%S”))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
loadtxt中的文件“/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/Python/numpy/lib/npyio.py”,第839行
VAL=[VAL[i]表示使用中的i]
索引器:列表索引超出范围
有人知道我如何做到让Python忽略空单元格并读取每列中可用的任何数据吗


谢谢

在不抓取
numpy
pandas
的情况下,让我们看看如何“手动”阅读此内容

首先认识到时间戳总是在同一个位置,后面跟着
“SATID”
,因此您可以执行
.split('SATID')[0]
来获取该信息

然后,如果您对信息的其余部分执行
.split('SATID')
,您将获得所有必需的信息,然后您可以进一步拆分这些信息

在代码中,这看起来像这样:

Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30
Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30
Timestamp: 00:49:14                                     SATID 14 VAL1 22 VAL2 265 SIGNAL 30
raw_data = ["Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30",
            "Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37                                     SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30",
            "Timestamp: 00:49:14                                     SATID 14 VAL1 22 VAL2 265 SIGNAL 30"]

output = []
for line in raw_data:
    if 'SATID' in line:  #making sure it is not an empty line
        timestamp = line.split(' SATID ')[0].split('Timestamp: ')[1].rstrip(' ')
        data = line.split(' SATID ')[1:]
        for record in data:
            if 'VAL1' in record:  #making sure it is not an empty record
                satid = record.split(' VAL1 ')[0]
                val1 = record.split(' VAL1 ')[1].split(' VAL2 ')[0]
                val2 = record.split(' VAL2 ')[1].split(' SIGNAL ')[0]
                signal = record.split(' SIGNAL ')[1].rstrip(' ')
                output.append({'Timestamp':timestamp,
                               'SATID':satid,
                               'VAL1':val1,
                               'VAL2':val2,
                               'SIGNAL':signal})


# output is now a list of dictionaries
for d in output:
    print(d)

由于列边不相交,您可以将文件视为固定宽度文件,并使用函数
read_fwf
。您必须准备列规范列表—指定每个列的第一个和最后一个位置的元组列表。以下是规格说明的开头(这很无聊,但您只需执行一次):


文件中的列具有固定的宽度。您可能应该使用Pandas.Hi-DYZ中的
pd.read_fwf()
。不幸的是,这些列的宽度有时略有不同……相邻列中的值是否重叠?如果没有(如您的示例中所示),您仍然可以将其视为fixed-width.DYZ,感谢您的提示。pd.read_fwf()的使用你有没有关于我如何使用这个模块的例子?谢谢顺便说一句,没有列重叠,所以我认为可以使用您建议的方法…谢谢Edwin。。。看起来是一种巧妙的方法。然而,有一个问题:如何才能保留每一列,并将其内容分配给特定变量,如最初显示的示例中所示?(请参阅上面的:time、sat1、sat2、sat3、sat4)您可以使用“词典列表”执行任何您想要的操作,或者您可以在循环时修改以执行自己的操作,这可以代替
output.append()
。请记住,第一个循环是逐行的,为了获得时间戳,第二个循环是该行中的逐条记录。这个例子只是想让你思考一下,并且只使用标准函数,你真的应该研究pandas,这在一篇评论中提到过。