Python - 遍历数据框并创建 class 个对象

Python - Loop though dataframe and create class objects

我有以下数据框(已经处理和清理以删除特殊字符等)。

parent_id members_id item_id item_name
par_100 member1 item1 t shirt
par_100 member1 item2 denims
par_102 member2 item3 shirt
par_103 member3 item4 shorts
par_103 member3 item5 blouse
par_103 member4 item6 sweater
par_103 member4 item7 hoodie

和以下 class 结构

class Member:
    
    def __init__(self, id):
        self.member_id = id
        self.items = []
        
class Item:
    
    def __init__(self, id, name):
        self.item_id = id
        self.name = name

数据框中的行数约为 500K+。我想创建一个字典(或其他结构),其中“parent_id”是主键,列映射到 class 对象。创建指定的数据结构后。我将根据一些业务逻辑执行一些操作,我将不得不遍历所有成员。

第一步是从数据帧创建数据结构。我有以下代码可以完成这项工作,但处理所有 500k+ 行需要大约 3 个小时。

# sorted_data is the dataframe mentioned above
parent_key_list = sorted_data['parent_id'].unique().tolist()
    
    for index, parent_key in enumerate(parent_key_list):
    
        temp_data = sorted_data.loc[sorted_data['parent_id'] == parent_key]
        unique_members = temp_data["members_id"].unique()
    
        for us in unique_members:
            items = temp_data.loc[temp_data['members_id'] == us] 
           
            temp_member = Member(items[0]["members_id"])
    
            for index, row in items.iterrows():
                temp_member.items.append(Item(row["item_id"], row["item_name"]))
    
        parent_dict[parent_key].append(temp_member)

由于 .loc 是非常耗时的操作,我尝试用 numpy 数组做同样的事情,但性能要差得多。有没有更好的方法来减少处理时间?

您可以使用 iterrows 或 itertuples 来迭代数据框并初始化您的实例。为了让它更容易一点(如果你坚持class,我个人会为成员和项目使用字典),我会做以下事情:

  • 将会员 ID 属性 添加到项目
  • 迭代数据框并仅初始化项目实例
  • 之后,您可以检查所有项目实例,以便识别唯一成员及其项目

试试这个:

from collections import defaultdict

parent_dict = defaultdict(lambda: [])

for (parent_id, members_id), sdf in sorted_data.groupby(['parent_id', 'members_id']):
    member = Member(members_id)
    items = sdf.apply(lambda r: Item(r.item_id, r.item_name), axis=1).to_list()
    member.items.extend(items)
    parent_dict[parent_id].append(member)

它利用.groupby函数为每个成员划分数据集。然后,您可以在 .groupby 生成的子数据帧上使用 .apply 创建项目对象,并将其转换为列表 if Item 对象,然后您可以使用它来更新每个成员 items属性。结果成员存储在 defaultdict 中,您可以使用 dict() 将其转换回普通成员(尽管它们的工作方式完全相同)。