【问题标题】:Create custom objects from CSV rows从 CSV 行创建自定义对象
【发布时间】:2019-11-16 00:30:39
【问题描述】:

我有以下 CSV 文件:

id;area;zz;nc
1;35.66;2490.8;1
2;65.35;2414.93;1
3;79.05;2269.33;1
4;24.5;2807.68;1
5;19.31;2528.59;1
6;25.51;2596.44;1

其中每一行代表一个所谓的 Cell 对象及其 id、area、zz、cc。

因此,我创建了以下类:

class cells():
    #    
    # Initializer / Instance Attributes
    def __init__(self, idm, area,zz,nc):
        self.idm  = idm
        self.area = area

这个想法是创建一些对象作为单元格的数量,并根据文件中的数据为其分配属性。

我的第一个想法是将 csv 文件作为 DataFrame 读取,然后读取要在循环中填充的对象列表。

据我所知,python 的循环效率非常低,我想知道是否有另一种方法(智能)来做到这一点。

谢谢, 迭戈

【问题讨论】:

  • 你的预期输出是什么?
  • 有什么特殊原因需要它们成为特定类的对象吗?你可以改用namedtuples 吗?
  • 另外,你的类应该命名为Cell而不是cells,因为Python类遵循CapWords命名约定,每个对象代表一个单元格。
  • 您对当前的答案是否满意,您希望得到新的答案吗?

标签: python pandas dataframe object cycle


【解决方案1】:

我不太明白您所说的循环是什么意思,但这将为您拥有的每一行创建一个单元格对象列表 - 给定您的数据格式。

对系列的熊猫列表理解是一个合理的选择,请参阅https://stackoverflow.com/a/55557758/7582537

试试这个:

import pandas as pd 


class Cell():
    # Initializer / Instance Attributes
    def __init__(self, idm, area, zz, nc):
        self.idm  = idm
        self.area = area


def create_cells(row):
    newcell = Cell(row[0], row[1], row[2], row[3])
    return newcell


file = pd.read_table("your_file.csv", sep=';')
zipp = zip(file['id'], file['area'], file['zz'], file['nc'])
cells = [create_cells(row) for row in zipp]

print(cells)

【讨论】:

  • 感谢分享这篇文章,内容丰富!
  • 我犹豫了一会儿。我确实同意在这里使用列表推导或某种其他类型的普通 Python 迭代可能有意义,但我不喜欢使用 pd.read_table() 并为构造函数中的元组解包创建一个完整的函数。回想起来,我应该对这些发表评论,而不仅仅是投反对票,抱歉。对于它的价值,我支持你知道,因为解决方案最终是正确的并且通常写得很好:)
  • 我认为一个关键的功能是“zip”。我必须正确理解它。
  • @diedro zip() 很棒,非常有用的功能。这是一个内置函数,我认为the docs 很好地解释了它。
  • @AlexanderCécile 是的,我在研究 pd.read_table 后更改了它 - 因为它适合读取非 csv 文件而不是 read_csv。但是是的,我同意,前提仍然成立,没有理由在这里使用pandas
【解决方案2】:

我认为在这种情况下您不需要熊猫。如果您只需要读取 csv 文件,pandas 就大材小用了。

要么直接阅读:

objects = []
next(f) # skip header row
with open('your_file', 'r') as f:
    for row in f:
        objects.append(cells(*row.strip().split(';')))

或使用csv 模块。

【讨论】:

    【解决方案3】:

    uMdRupert 在他的回答中分享了一个有趣帖子的链接,我建议您查看一下!


    我喜欢他使用列表推导的想法,所以我想分享一个类似的方法:

    import pandas as pd
    
    
    class Cell:
        def __init__(self, idm, area, zz, nc):
            self.idm = idm
            self.area = area
    
    
    cell_df = pd.read_csv('../resources/test_cell_data.csv', delimiter=';')
    cell_df = cell_df.rename({'id': 'idm'}, axis='columns')
    
    cell_objs_lst = [Cell(*curr_tuple._asdict()) for curr_tuple in cell_df.itertuples(index=False)]
    

    Pandas 可能对这个任务来说太过分了,所以这里有一个非常简单的方法,它使用了 csv 模块:

    import csv
    
    
    class Cell:
        def __init__(self, idm, area, zz, nc):
            self.idm = idm
            self.area = area
    
    
    with open('../resources/test_cell_data.csv', newline='') as in_file:
        next(in_file)
        reader = csv.DictReader(in_file, fieldnames=['idm', 'area', 'zz', 'nc'], delimiter=';')
        cells_lst = [Cell(**curr_row) for curr_row in reader]
    

    【讨论】:

      【解决方案4】:

      我不知道您为df 的每一行使用对象Cells 的目的。但是,我认为您可以使用df.agg 来实现它并将每个对象保持在一个系列中

      class Cells():
          # Initializer / Instance Attributes
          def __init__(self, idm, area, zz, nc):
              self.idm  = idm
              self.area = area
              self.zz = zz
              self.nc = nc
      
      s = df.agg(lambda x: Cells(*x), axis=1)
      print(s)
      
      Output:
      0    <__main__.Cells object at 0x09FA38D0>
      1    <__main__.Cells object at 0x09FA3510>
      2    <__main__.Cells object at 0x09FA3870>
      3    <__main__.Cells object at 0x09FA3AF0>
      4    <__main__.Cells object at 0x09B27790>
      5    <__main__.Cells object at 0x09B27770>
      dtype: object
      

      之后,您可以通过s 的索引访问每个对象

      In [303]: s[0].__dict__
      Out[303]: {'idm': 1.0, 'area': 35.66, 'zz': 2490.8, 'nc': 1.0}
      
      In [304]: s[1].__dict__
      Out[304]: {'idm': 2.0, 'area': 65.35, 'zz': 2414.93, 'nc': 1.0}
      

      【讨论】:

      • df 来自哪里?
      • @AlexanderCécile:在熊猫世界中,df 始终被称为工作数据框。 OP 说The first idea that I have is to read the csv file as a DataFrame,所以我假设他已经知道将 csv 读取到数据帧的方法。如果他不这样做,一个简单的谷歌就会给他 read_csv 的指令。
      • 是的,我对惯例很熟悉,我想我是措手不及,因为我只看了你在帖子开头提到的df掌心
      猜你喜欢
      • 2015-05-15
      • 2016-02-20
      • 1970-01-01
      • 2018-04-19
      • 2018-09-07
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      相关资源
      最近更新 更多