【问题标题】:Parse CSV records into a list of Classes [duplicate]将 CSV 记录解析为类列表 [重复]
【发布时间】:2013-04-04 17:16:35
【问题描述】:

我在 StackOverflow 上的第一篇文章,虽然我已经阅读了几年!

我正在使用 Python 清理和分析 IV 曲线的 CSV 数据转储。

我的基本问题是数据记录器给我的格式:每隔几分钟,在一个时间实例中,需要对电压 (v)、电流 (i) 和功率 (p) 进行大约 100 次测量,然后转储将它们转换为 CSV 文件。下一个测量值被附加到此。所以,我们得到的数据结构是:

Date1;0.2;0.1;0.02
Date1;0.3;0.1;0.03
Date1;0.4;0.1;0.04
Date2;0.2;0.1;0.02
Date2;0.3;0.1;0.03
Date2;0.4;0.1;0.04
Date3; etc...

此数据存储在文件 Data.csv 中

我编写了一个名为 IVCurve 的类:

class IVCurve:
    def __init__(self, datetime):
        self.datetime = datetime
    v = []
    i = []
    p = []

我想创建一个这些类实例的列表:

count = -1
thelist = []
prev_time = 0

import csv

with open('Data.csv', 'rb') as IVdump:
    IVdata = csv.reader(IVdump, delimiter=';')
    for datetime, v, i, p in IVdata:
        # if we're onto a new date
        if prev_time != datetime:
            # note the new record
            prev_time=datetime
            #go to the next position in thelist[]
            count +=1
            #create a new curve
            thelist.append(IVCurve(datetime))
        # in any case, put the values of v, and i into this thelist[count]
        thelist[count].v.append(float(v))
        thelist[count].i.append(float(i))
        thelist[count].p.append(float(v)*float(i))

我遇到的问题是 v 和 i 的所有值都放置在 thelist[] 的每个实例中,即,我得到一个 IVCurve 实例列表,每个实例都有不同的日期时间,但每个实例都有同一组 v、i 和 p(并且该组代表所有日期组合的整个数据集)。

我不明白我在这里做错了什么。在我看来,每次 count 增加(每次我们找到一个新日期),thelist[count] 应该是一个新的、唯一的记录。

我已在此处粘贴的示例数据(我已与此代码一起使用):http://pastebin.com/Dw4dd7tu

所以问题是:如何分离这些值?

非常感谢您的帮助!

【问题讨论】:

  • 不要给可变类设置类属性,见How do I avoid having Python class data shared among instances?v = []等会导致问题。
  • Martijn,感谢您的快速回复!我阅读了那篇文章,并将类更改为将 v、i、p 放入 init 函数中,但是现在我收到错误 AttributeError: IVCurve instance has no attribute 'v'
  • 没关系,我忘了添加 self.v 等
  • 谢谢!这就是答案,我只是不知道该怎么问!

标签: python parsing csv


【解决方案1】:

问题是你有

class IVCurve:
    def __init__(self, datetime):
        self.datetime = datetime
    v = []
    i = []
    p = []

这些列表然后是类上的列表。所以类的每个实例都有相同的列表。您希望每个实例的列表都不同,因此您应该在 __init__ 方法中创建它们。

class IVCurve:
    def __init__(self, datetime):
        self.datetime = datetime
        self.v = []
        self.i = []
        self.p = []

【讨论】:

  • 谢谢! Martijn Pieters 击败了你,但无论如何都非常感谢!
【解决方案2】:

这是否提供所需的输出?

import csv
import pprint


class IVCurve(object):
    def __init__(self, datetime, v=None, i=None):
        self.datetime = datetime
        self.v = []
        self.i = []
        self.p = []
        if v and i:
            self.add_data(v, i)

    def add_data(self, v, i):
        self.v.append(float(v))
        self.i.append(float(i))
        self.p.append(float(v) * float(i))

    def __repr__(self):
        return 'IVCurve (datetime: {}, v: {}, i: {}, p: {})'.format(
                self.datetime, self.v, self.i, self.p)


thelist = []

with open('Data.csv', 'rb') as ivdump:
    ivdata = csv.reader(ivdump, delimiter=';')
    datetime, v, i, p = next(ivdata)
    thelist.append(IVCurve(datetime, v, i))
    for datetime, v, i, p in ivdata:
        if datetime != thelist[-1].datetime:
            thelist.append(IVCurve(datetime, v, i))
        else:
            thelist[-1].add_data(v, i)

pprint.pprint(thelist)

【讨论】:

  • 看起来很复杂......我必须了解更多才能理解这一点!不过我会试试的
  • 这与我最终实现的非常接近。我接受了另一个答案,因为它准确地指出了问题所在。谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 2021-09-05
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多