【问题标题】:Saving multiple csv files with diferent names that change dependent on variable value - python保存具有不同名称的多个csv文件,这些文件根据变量值而变化 - python
【发布时间】:2020-03-27 23:40:48
【问题描述】:

第一次在这里问问题,虽然我已经使用了很多,它真的很有帮助。我已经搜索过了,但找不到答案。

我的程序将持续接收汽车数据,我想将其保存到多个 csv 文件中。 我想为每一圈存钱。所以对于 Lap1,我会有 car_data_1.csv 之类的东西,对于第二圈 car_data_2.csv 等等。

我知道如何强制执行,使用名称创建每个文件并将结果附加到该特定文件。但是由于我不知道我将有多少圈,在我看来这不是正确的方法和最好的方法。

所以在下面的代码中,当我创建 with open ('car_data_(LapNumber).csv', 'w') as csv_file: 行时,我希望程序创建一个名为 car_data_1 的文件,因为我将从第 1 圈开始。所以 LapNumber(该行中的括号内只是为了向您展示) 是我的变量的名称,它会改变,我想保存每个 csv 和每个圈的数据。

import socket
import csv

'''UDP SET UP'''

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
UDP_IP = 'IP'
UDP_PORT = Port

sock.bind((UDP_IP, UDP_PORT))

'''CSV SET UP'''

fieldnames = ["On","Time","LapNumber","Engine","Speed","Power","BestLap","Distance"]

LapNumber=1

with open(f'car_data_{LapNumber}.csv','w') as csv_file:
    csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
    csv_writer.writeheader()

while True:

    data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
    values = struct.unpack("<iIffffff",data)

    LapNumber = values[2]

    with open(f'car_data_{LapNumber}.csv','a') as csv_file:
        csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
        #csv_writer.writeheader()

        info = {
            "On"    :values[0],
            "Time"  :values[1],
            "LapNumber" :values[2],
            "Engine"    :values[3],
            "Speed" :values[4],
            "Power" :values[5],
            "BestLap"   :values[6],
            "Distance"  :values[7],         
        }

        csv_writer.writerow(info)

我知道也许我必须更改结构,因为我认为我必须在条件 while 或类似的东西中创建 csv,因为如果我创建 csv 并在 @987654324 中附加值@ 它将不断覆盖 csv 上的值,我最终会得到最后一组值(在越过另一圈之前)。

你有什么建议?我一直在考虑添加一些forif,所以让我知道你们认为最好的选择。这个项目是最近的项目,我一直在逐步进行以确保一切正常,现在我想改进这个项目。

感谢您的帮助,如果您需要更多信息,请告诉我。 我正在使用 Windows、python 3.8 和 pycharm。

【问题讨论】:

    标签: python python-3.x csv pycharm export-to-csv


    【解决方案1】:

    您需要在文件名中使用格式变量

    with open('car_data_{}.csv'.format(LapNumber),'w')
    

    现在变量LapNumber被替换到字符串中,代替{}

    或者,如果您使用的是 Python 3.6 或更高版本,请使用 f-strings

    with open(f'car_data_{LapNumber}.csv','w')
    

    您当前的方法会创建文件名“car_data_(LapNumber.csv)”,但实际上并未将变量替换为字符串。

    对于您问题的第二部分,与编写标题有关 - 您希望保留对您正在写入的当前圈数的引用(它本身是您正在写入的 file 的代理)。当圈数发生变化时,您知道您正在写入一个新文件,并且需要添加一个标题。

    类似的东西;

    # Initialise writing_lap to lap number 1
    writing_lap = 1
    while True:
    
        data, addr = sock.recvfrom(1024)  # buffer size is 1024 bytes
        values = struct.unpack("<iIffffff",data)
    
        # Read the current lap
        current_lap = values[2]
    
        with open(f'car_data_{writing_lap}.csv','a') as csv_file:
            csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
            if current_lap > writing_lap:
                 # If the current_lap has increased, write the headers
                 csv_writer.writeheader()
                 # And remember to update the writing_lap variable
                 writing_lap = current_lap
    
            info = {
                "On"    :values[0],
                "Time"  :values[1],
                "LapNumber" :values[2],
                "Engine"    :values[3],
                "Speed" :values[4],
                "Power" :values[5],
                "BestLap"   :values[6],
                "Distance"  :values[7],         
            }
    
            csv_writer.writerow(info)
    
    

    【讨论】:

    • 谢谢@wstk!它现在确实会在每次汽车越线时创建一个新的 csv 文件。我根据您的建议编辑了上面的代码。但我注意到了一些事情,这是有道理的。 Lap1 的 csv 是完美的,但是当它为 Lap2 写入时,csv 文件会丢失标题。这是有道理的,因为标头是在无限循环之外创建的。关于如何纠正的任何想法?我不能只在循环中添加行csv_writer.writeheader(),因为它会在每次写入不断变化的值时写入标题。
    【解决方案2】:

    由于 wstk 已经回答了您的第一个问题,您在评论中的第二个问题是关于将标题添加到新文件。 (我无法评论,因为没有足够的声誉)

    要将标题添加到每个新的 csv 文件,您可以检查 LapNumber 何时更改并在此处添加标题。

    例如,在while循环内部:

    #LapNumber = values[2] --> you just need to move this line as below
    #instead of putting LapNumber inside {}, you can just put values[2], and use 
    #LapNumber for checking the condition of writing the header
    
    with open(f'car_data_{values[2]}.csv','a') as csv_file:
        csv_writer =csv.DictWriter(csv_file, fieldnames=fieldnames)
        if values[2] != LapNumber:
            csv_writer.writeheader()
            LapNumber = values[2]
    

    现在您的脚本只在创建新文件时写入标题。

    【讨论】:

      猜你喜欢
      • 2016-02-04
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 2019-12-25
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 2012-05-07
      相关资源
      最近更新 更多