首页 > 解决方案 > 如何识别缺失的索引

问题描述

我有一个包含数百万个索引点的文本文件,这些索引点都被解释为字符串并且是制表符分隔的。但是,可能会丢失一些索引点。这是我的文本文件的示例:

1       0       4         0d 07:00:37.0400009155273   
2       0       4         0d 07:00:37.0400009155273   
3       0       4         0d 07:00:37.0400009155273   
5       0       4         0d 07:00:37.0400009155273   
7       0       4         0d 07:00:37.0400009155273   
9       0       4         0d 07:00:37.0400009155273

请注意,缺少第 4、6 和 8 行。我的目标是创建一个可以解析文本文件、识别可能丢失的索引点并返回包含所有丢失索引点(如果有)的列表或不返回任何内容的函数。

我在 Spyder IDE Windows10 操作系统中使用 Python 3.7。我对 Python 和 Stackoverflow 比较陌生。

这就是我到目前为止所得到的。这适用于 ID 1 缺失索引,但如果有多个缺失索引点则失败。

错误在第一个 else 行之后开始。我不确定如何使用 for 循环的索引 (0, 1, 2, 3...) 跟踪文档中观察到的索引 (1, 2, 3, 5...),因为丢失的索引点会随着时间的推移而复合.

请注意,文本文档的前 4 行包含我在解析过程中忽略的标题信息,这就是为什么 data = f.readlines()[4:]

  def check_sorted_file(fileName):
        missing_idx = []
        count = 1
            with open(fileName, 'r') as f:
                data = f.readlines()[4:]
                for x, line in enumerate(data):
                    idx = int(line.split()[0])
                    if idx == (count + x): 
                        pass
                    else: 
                        missing_idx.append(count + x)
                        count += 1
                if missing_idx != []:
                    print('\nThe following idicie(s) are missing: ')
                    print(*missing_idx, sep=", ")
                else:   
                    print('\nAll indices are accounted for. ')
                return missing_idx

...

感谢您的任何帮助!

标签: pythonpython-3.xindexing

解决方案


您可以单独使用 Python 执行此操作:

with open(filename) as f:
    indices = [int(row.split('\t')[0]) for row in f.read().split('\n')[4:]]

missing_indices = [index 
                   for index in range(1, len(indices) + 1)
                   if index not in indices]

这会将您的数据转换为嵌套list,其中每个外部list包含一行,每个内部list包含一个元素。由于我们只关心索引,我们得到第一个元素并忽略其他元素。

然后,由于索引从 1 开始按运行顺序排列,我们构建了一个range跨越预期索引范围的索引,并获取存在于该范围内但不在文件中的索引。

假设索引是唯一的(这似乎是合理的),我们也可以使用DYZ的建议来使用sets

missing_indices = set(range(1, len(indices) + 1) - set(indices)

pandas也可以正常工作:

import pandas as pd

df = pd.read_csv(filename, sep='\t').iloc[4:]

range_index = pd.RangeIndex(1, len(df) + 1)
print(range_index[~range_index.isin(df.iloc[:, 0])]

这会pandas从您的数据中创建一个 DataFrame,切断前四行。遵循与另一个答案相同的原则,它创建一个包含所有预期值的索引,并获取 DataFrame 第一列中不存在的子集。


推荐阅读