我有一个看起来像这样的数据框(df):
HOUSEID PERSONID WHY_TRP
20000017 1 1
20000017 1 1
20000017 1 1
20000017 2 1
20000017 2 3
20000231 1 11
20000231 1 11
20000231 2 11
20000521 1 11
20000521 2 11
20000521 2 3
每一行都描述一个人的旅程。我有另一种相同类型的数据框,其中每一行都描述一个人(df_p):
HOUSEID PERSONID
20000017 1
20000017 2
20000231 1
20000231 2
20000521 1
20000521 2
我想在第二个数据框中添加三个新列,以显示每个人的1、3和11的频率。基本上,我已经有了另一个具有其他功能的数据帧(df_p),所以我不应该使用groupby。由于某些原因,第一个和第二个数据框的人数不相同。这就是为什么我需要以下策略。这是我尝试的代码,但要花几个小时才能完成(100万次迭代):
df_p.insert(2, 'WHY_TRP_1', 0)
df_p.insert(3, 'WHY_TRP_2', 0)
df_p.insert(4, 'WHY_TRP_3', 0)
def trip_counter(i, r):
if r[2] == 1:
df_p.loc[(df_p['HOUSEID'] == r[0]) & (df_p['PERSONID'] == r[1]), ['WHY_TRP_1']] += 1
elif r[2] == 3:
df_p.loc[(df_p['HOUSEID'] == r[0]) & (df_p['PERSONID'] == r[1]), ['WHY_TRP_3']] += 1
elif r[2] == 11:
df_p.loc[(df_p['HOUSEID'] == r[0]) & (df_p['PERSONID'] == r[1]), ['WHY_TRP_11']] += 1
for i ,r in df.iterrows():
trip_counter(i ,r)
输出:
HOUSEID PERSONID WHY_TRP_1 WHY_TRP_3 WHY_TRP_11
20000017 1 3 0 0
20000017 2 1 1 0
20000231 1 0 0 2
20000231 2 0 0 1
20000521 1 0 0 1
20000521 2 0 1 1
有更快的方法吗?
谢谢
答案 0 :(得分:1)
使用pd.get_dummies
,.groupby().sum()
和pd.merge()将其返回到原始数据帧中(编辑:我刚才在pd.merge
逻辑中添加了内容,以在回答后完全回答您的问题再看一遍。这个答案吗?)
df1 = pd.get_dummies(df, columns=['WHY_TRP']).groupby(['HOUSEID', 'PERSONID']).sum().reset_index()
df2 = pd.merge(df, df1, how='left', on=['HOUSEID', 'PERSONID'])
df2
答案 1 :(得分:0)
IIUC:
(df.groupby(['HOUSEID','PERSONID'])
.WHY_TRP.value_counts()
.unstack(fill_value=0)
.add_prefix('WHY_TRP_')
.reset_index()
)
输出:
WHY_TRP HOUSEID PERSONID WHY_TRP_1 WHY_TRP_3 WHY_TRP_11
0 20000017 1 3 0 0
1 20000017 2 1 1 0
2 20000231 1 0 0 2
3 20000231 2 0 0 1
4 20000521 1 0 0 1
5 20000521 2 0 1 1