如何操作文本文件中的数据

时间:2018-03-16 17:04:21

标签: python arrays csv data-manipulation

我正在尝试制作一个程序,它接受一个整数的大数据文件并以不同的格式创建一个新的csv,它需要30行的x,y,z并将它们合并为一行。

大型数据集的格式为(timestamp, x,y,z

例如:

0.000, 5, 6, 8,

1.000, -6, 7, 9,

2.000, -15, 25, 23,

或:

timestamp, x1, y1, z1

timestamp, x2, y2, z2

timestamp, x3, y3, z3

新数据集如下所示:

delta timestamp, x1, y1, z1, x2, y2, z2, x3, y3, z3....x30, y30, z30,

delta timestamp, x31, y31, z31, x32, y32, z32, x33,... x60, y60, z60,

等..(每行包含30个x,y,z' s

我想到可能每30行附加一个\ n,然后用逗号替换每个新行。我的代码不起作用。它只是为新数据的位置添加了一个逗号:

timestamp, x1, y1, z1,, timestamp, x2, y2, z2,, timestamp... 

你们有什么想法吗?

list = []
import csv
i=0
results = []
with open('bikefall.csv', newline='') as inputfile:
    for row in csv.reader(inputfile):
        i+=1
        if i%30==0:
            results.append(row)
            results.append('\n')
        else:
            results.append(row)

print("\n".join([item.replace('\n', ',') for item in 
open('bikefall.csv').read().split('\n\n')]))

3 个答案:

答案 0 :(得分:0)

我不知道你如何计算delta,所以我只是放了一个占位符函数。

关于您的代码,您可以使用enumerate稍微改进一下,这样您就不必手动更新i

您还可以使用slice notation获取csv文件中每行的前4项。

import csv

def calculate_delta(timestamps):
    pass

output = ""

with open('bikefall.csv', "r") as inputfile:
    timestamps = []
    results = []
    for i, row in enumerate(csv.reader(inputfile)):
        timestamp, x, y, z = row[:4]
        timestamps.append(timestamp)
        results.extend((x, y, z))
        if len(timestamps) == 30:
            delta = calculate_delta(timestamps)
            str_timestamps = ", ".join(results)
            output += "{}, {}\n".format(delta, str_timestamps)
            timestamps = []
            results = []

print(output)

此代码有一个错误,当您的CSV中只有29行时会发生什么?

这29行将被忽略,因此你仍然需要检查当前行是否是csv文件中的最后一行,并相应地处理它。

答案 1 :(得分:0)

一种方法是一次以30块的形式读取您的CSV文件。然后组合这些行。我假设delta是通过从每个块的最后一个时间戳中减去第一个时间戳来计算的(另一种可能性是每个块的开始之间的差异,所以首先是0?):

from itertools import zip_longest
import csv

f_input = open('bikefall.csv', newline='')
f_output = open('output.csv', 'w', newline='')

with f_input, f_output:
    csv_input = csv.reader(f_input)
    csv_output = csv.writer(f_output)

    for rows in zip_longest(*[iter(csv_input)] * 30, fillvalue=None):
        rows = [[float(row[0])] + row[1:] for row in rows if row]
        delta = rows[-1][0] - rows[0][0]
        combined = [delta]

        for row in rows:
            combined.extend([row[1], row[2], row[3]])

        csv_output.writerow(combined)

分组基于Python文档中的itertools grouper()配方。

答案 2 :(得分:0)

zip这是一个完美的工作。这是一个解决方案,比以前的答案更加pythonic:

with open('bikefall.csv') as inputfile:
    # version using csv reader
    matrix = [[line[0],','.join(line[1:])] for line in csv.reader(inputfile)]
    # version using standard text file reader
    #matrix = [line.strip().split(',', maxsplit=1) for line in inputfile]

stamps, coords = zip(*matrix) # split matrix into stamps and coords

for n in range(0, len(stamps), 30):
  print(','.join((stamps[n],) + coords[n:n+30]))

注意:由于切片表示法,可能少于30项的最后一行是自动管理的。