如何遍历 .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 - 过滤掉包含具有特定值的行的分区或行组