从 CSV 行创建自定义对象
Create custom objects from CSV rows
我有以下 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:
class cells():
#
# Initializer / Instance Attributes
def __init__(self, idm, area,zz,nc):
self.idm = idm
self.area = area
想法是创建多个对象作为单元格的数量,并根据文件中的数据为它们分配属性。
我的第一个想法是将 csv 文件作为 DataFrame 读取,然后循环填充对象列表。
据我所知,python 的循环效率很低,我想知道是否有另一种方法(聪明的方法)来做到这一点。
谢谢,
迭戈
我不太明白你所说的循环是什么意思,但这将为你拥有的每一行创建一个单元格对象列表 - 考虑到你的数据所处的格式。
Pandas 对序列的列表理解是一个合理的选择,参见
试试这个:
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)
我不知道您为 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}
uMdRupert 在他的回答中分享了一个 link 到一个有趣的 post,我建议你去看看!
我喜欢他使用列表理解的想法,所以我想分享一个类似的方法:
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]
我认为在这种情况下您不需要 pandas。如果您只需要读取一个 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
模块。
我有以下 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:
class cells():
#
# Initializer / Instance Attributes
def __init__(self, idm, area,zz,nc):
self.idm = idm
self.area = area
想法是创建多个对象作为单元格的数量,并根据文件中的数据为它们分配属性。
我的第一个想法是将 csv 文件作为 DataFrame 读取,然后循环填充对象列表。
据我所知,python 的循环效率很低,我想知道是否有另一种方法(聪明的方法)来做到这一点。
谢谢, 迭戈
我不太明白你所说的循环是什么意思,但这将为你拥有的每一行创建一个单元格对象列表 - 考虑到你的数据所处的格式。
Pandas 对序列的列表理解是一个合理的选择,参见
试试这个:
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)
我不知道您为 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}
uMdRupert 在他的回答中分享了一个 link 到一个有趣的 post,我建议你去看看!
我喜欢他使用列表理解的想法,所以我想分享一个类似的方法:
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]
我认为在这种情况下您不需要 pandas。如果您只需要读取一个 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
模块。