如何遍历 .dat 文件并将每组行的特定列附加到数组

Posted

技术标签:

【中文标题】如何遍历 .dat 文件并将每组行的特定列附加到数组【英文标题】:How to loop over .dat file and append specific column per set of lines to an array 【发布时间】:2020-02-20 23:19:21 【问题描述】:

在 .dat 文件中,第一行 [它是一个整数,我称为 S)表示存在的集合数,也表示每个集合的变体数。例如,如果 S 为 21,则每 21 行中有 21 个集合。

然后,从下一行开始有 6 列。我想将每组 S 行的第 4 列附加到一个数组中,以便稍后进行一些计算。我想停止这样做,直到第 S*S 行。复杂之处在于我需要忽略(不要附加)每组的每 21 行,因为它们是虚构的结果。

我不完全确定该怎么做,但这是我现在得到的。感谢您的帮助。

with open('foo.dat') as f:

    S = int(f.readline())  #extracting set number
    print("Sets, S:", S)

    I   = [] 

    for i, lines in enumerate(f):
        columns = lines.split()

        if i < S*S: 

            In = float(columns[3])                                                            
            I.append(In)   #extracting 4th column

    #checking results        
    print(I)
    print("length of I:", len(I))

请找到我正在使用的示例 .dat 文件的附加链接:https://pastebin.com/Cgms3efh

预期输出:

I1 = [140.66758,46.745557,20.931668,10.599119,5.4772385,2.9093667,1.713973,1.1483754,0.83311013,0.62603209,0.47950916,0.37391387,0.29780616,0.2431309,0.20399252,0.17613667,0.15656772,0.14322945,0.13475736,0.13030334] P>

I2 = [46.745557,28.637786,16.271265,9.0978727,4.9856322,2.7981477,1.7304986,1.1918406,0.87493924,0.66197242,0.5100049,0.39981398,0.31993277,0.2622417,0.22075246,0.19110705,0.17021343,0.1559358,0.14684993,0.14206743] P>

...

注意:我实际上不需要将它们全部保存,因为我会在传递到下一组 21-1 行之前对每组进行计算。 所以我可以为每组新的行覆盖数组。

【问题讨论】:

可能会显示您预期输出的样本 好的,我加一下 您的代码对我来说运行良好。您面临什么问题? @beer44,现在我的代码正在提取整个第 4 列直到第 S*S 行,但我试图每组 20 行提取它们并在组之间跳过一行。我完全不知道如何处理它。 所以你需要跳过每一个 21、41 行,等等? 【参考方案1】:

这是一个带有嵌套列表理解的简单实现:

with open('test.dat', 'r') as file:
    num = int(file.readline().strip())
    data = [[float(file.readline().split()[3]) for i in range(num)][:-1] for j in range(num)]

然后您只需访问您的data[0] 用于第一组,data[1] 用于第二组,依此类推...

print(data[0])
# [140.66758, 46.745557, 20.931668, 10.599119, 5.4772385, 2.9093667, 1.713973, 1.1483754, 0.83311013, 0.62603209, 0.47950916, 0.37391387, 0.29780616, 0.2431309, 0.20399252, 0.17613667, 0.15656772, 0.14322945, 0.13475736, 0.13030334]
print(data[1])
# [46.745557, 28.637786, 16.271265, 9.0978727, 4.9856322, 2.7981477, 1.7304986, 1.1918406, 0.87493924, 0.66197242, 0.5100049, 0.39981398, 0.31993277, 0.2622417, 0.22075246, 0.19110705, 0.17021343, 0.1559358, 0.14684993, 0.14206743]

如果您不需要存储所有数据,可以使用生成器代替:

def set_gen(filename):
    with open(filename, 'r') as file:
        num = int(file.readline().strip())
        for _ in range(num):
            yield [float(file.readline().split()[3]) for i in range(num)][:-1]

my_sets = set_gen('test.dat')
print(next(my_sets))

【讨论】:

这很漂亮 哇,这是最好的效率!感谢您提供精美简洁的代码 Python 的列表/字典理解非常方便。您使用它们的次数越多,它就越有意义并更好地应用于您的解决方案。如果您确实有大量数据,请参阅我更新的生成器解决方案。编码愉快!【参考方案2】:

您可以使用模运算符来计算您是否在第 21 个元素上。如果该数字正好除以 21,则它是该集合的第 21 行。为了使其更通用,我根据设置的大小制作了模数。

with open('query4.txt') as f:
    sets = int(f.readline())  #extracting set number
    limit = sets * sets
    items = []
    print("Sets:", sets, ", limit:", limit)

    for index, line in enumerate(f):
        columns = line.split()
        num = float(columns[3])
        #add one to the index and check if its divisable by the set size.
        if (index + 1) % sets:
            #we got here if this number cannot be devided by the set sizze without a remainder I.E this line is not the last line of the set
            items.append(num)  # extracting 4th column 
        else:
            #we got here if we are on the last line of the set size so print the dta and reset the list.
            print(items)
            items = []
        if index > limit:
            #break the loop when we reach the limit
            break

样本输出

Sets: 21 , limit: 441
[140.66758, 46.745557, 20.931668, 10.599119, 5.4772385, 2.9093667, 1.713973, 1.1483754, 0.83311013, 0.62603209, 0.47950916, 0.37391387, 0.29780616, 0.2431309, 0.20399252, 0.17613667, 0.15656772, 0.14322945, 0.13475736, 0.13030334]
[46.745557, 28.637786, 16.271265, 9.0978727, 4.9856322, 2.7981477, 1.7304986, 1.1918406, 0.87493924, 0.66197242, 0.5100049, 0.39981398, 0.31993277, 0.2622417, 0.22075246, 0.19110705, 0.17021343, 0.1559358, 0.14684993, 0.14206743]
[20.931668, 16.271265, 11.032549, 6.8871422, 4.1249159, 2.5314457, 1.684505, 1.2087469, 0.90466792, 0.69278056, 0.53932924, 0.42681753, 0.34438866, 0.28428271, 0.24069443, 0.20932984, 0.18709735, 0.171836, 0.16209171, 0.15695167]

【讨论】:

啊,很好,这是我比较熟悉的东西。非常感谢!

以上是关于如何遍历 .dat 文件并将每组行的特定列附加到数组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多组行的数字更新列?

将CSV文件数据读取为命名元组行的pythonic方法是啥?

如何将组行附加到数据框中

Oracle SQL - 过滤掉包含具有特定值的行的分区或行组

如何在 python 中遍历大型 CSV 文件时轻松使用内存?

匹配列并附加到数据框,Python 3.6