我编写了一些代码来映射两个数据帧的ID,如果条件匹配,那么在现有数据帧的指定列中创建一个计数,我正在寻找一种更有效的计算方法。
示例数据
import numpy as np
import pandas as pd
d = {'ID' : pd.Series([111, 222, 111, 444, 222, 111]), 'Tag' : pd.Series([1, 2, 3, 1, 2, 1])}
df1 = (pd.DataFrame(d))
print(df1)
ID Tag
0 111 1
1 222 2
2 111 3
3 444 1
4 222 2
5 111 1
d = {'ID' : pd.Series([111, 444, 666, 444, 777])}
df2 = (pd.DataFrame(d))
print(df2)
ID
0 111
1 444
2 666
3 444
4 777
df2['tag1'] = 0
df2['tag2'] = 0
df2['tag3'] = 0
for index, row in df2.iterrows():
for i, t in df1.iterrows():
if row['ID'] == t['ID']:
if t['Tag'] == 1:
df2.loc[index]["tag1"] += 1
elif t['Tag'] == 2:
df2.loc[index]["tag2"] += 1
elif t['Tag'] == 3:
df2.loc[index]["tag3"] += 1
输出
print(df2)
ID tag1 tag2 tag3
0 111 2 0 1
1 444 1 0 0
2 666 0 0 0
3 444 1 0 0
4 777 0 0 0
最有效的方法是什么,而不是迭代计算?
注意,df1可以多次包含样本ID
,但值Tag
(df1和df2是大型数据帧,df1为50,000行,df2为15,000)
答案 0 :(得分:2)
print (pd.crosstab(df1.ID, df1.Tag))
Tag 1 2 3
ID
111 2 0 1
222 0 2 0
444 1 0 0
print (pd.merge(df2, pd.crosstab(df1.ID, df1.Tag)
.add_prefix('tag')
.reset_index(), on='ID', how='left')
.fillna(0)
.astype(int))
ID tag1 tag2 tag3
0 111 2 0 1
1 444 1 0 0
2 666 0 0 0
3 444 1 0 0
4 777 0 0 0
相反crosstab
您可以groupby
与size
和unstack
使用{{3}}:
print (df1.groupby(['ID', 'Tag'])['Tag'].size().unstack())
Tag 1 2 3
ID
111 2.0 NaN 1.0
222 NaN 2.0 NaN
444 1.0 NaN NaN
print (pd.merge(df2, df1.groupby(['ID', 'Tag'])['Tag'].size().unstack()
.add_prefix('tag')
.reset_index(), on='ID', how='left')
.fillna(0)
.astype(int))
ID tag1 tag2 tag3
0 111 2 0 1
1 444 1 0 0
2 666 0 0 0
3 444 1 0 0
4 777 0 0 0