最快的方式添加列时,有相互依赖?

2024-10-02 18:23:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理一个带有家庭信息的数据框的问题。每个家庭由一个或多个父母和孩子组成。每个人都有一个唯一的UserID,每个家庭都有一个唯一的FamilyID。一个人只能属于一个家庭。“类型”列指示此人是家长还是孩子,年龄指示用户的年龄

我想添加一个名为ParentAge for children的列,指出最年长父母的年龄

import pandas as pd
import numpy as np

#example data
df = pd.DataFrame([[1, 22, 'Child', 8], 
                   [1, 62, 'Parent', 36],
                   [2, 102, 'Child', 6],
                   [2, 103, 'Child', 10],
                   [2, 107, 'Parent', 40],
                   [2, 108, 'Parent', 42]], 
                  columns=['FamilyId', 'UserId', 'Type', 'Age'])

expected_result = pd.DataFrame([[1, 22, 'Child', 8, 36], 
                   [2, 102, 'Child', 6, 42],
                   [2, 103, 'Child', 10, 42]], 
                  columns=['FamilyId', 'UserId', 'Type', 'Age', 'ParentAge'])

以下是我迄今为止尝试过的方法(我尝试过其他几种方法,但性能大致相似)

parents = df.query('Type=="Parent"')
children = df.query('Type=="Child"')

oldest_parents = parents.groupby('FamilyId') \
    .apply(pd.DataFrame.nlargest, n=1, columns='Age') \
    .reset_index(drop=True) \
    .rename(columns={'Age': 'ParentAge'})

pd.merge(children, oldest_parents[['FamilyId', 'ParentAge']], on='FamilyId')

上面的方法是可行的,但是对于一个接近一百万行的数据帧,它需要20多个小时才能完成。所有其他的技术都是一样的。我用dplyr库在R中花了几秒钟的时间。我想知道是否有一个更快的方法来实现这一点


Tags: columns方法childdataframedfagetype家庭
1条回答
网友
1楼 · 发布于 2024-10-02 18:23:03

选项1:尝试groupby().max()而不是apply

df[df['Type'].eq('Child')].merge(df[df['Type'].eq('Parent')].groupby('FamilyId').Age.max(),
                                 on='FamilyId',
                                 suffixes=('','Parent'))

选项2:最快,假设最年长的父母也是家中最年长的

df['Parent_Age'] = df.groupby('FamilyId').Age.transform('max')
df[df['Type'].eq('Child')]

选项3:更快,无需假设父母年龄最大(例如,授予父母):

df['Parent_Age'] = (df['Age'].mul(df['Type'].eq('Parent'))
                             .groupby(df['FamilyId']).transform('max')
                   )
df[df['Type'].eq('Child')]

输出

   FamilyId  UserId   Type  Age  AgeParent
0         1      22  Child    8         36
1         2     102  Child    6         42
2         2     103  Child   10         42

相关问题 更多 >