我无法从另一个数据框中的一个数据框中搜索一个数字列表。我正在处理一个案例,其中不同的数字指的是同一个项目。 我无法从另一个数据框中的一个数据框中搜索一个数字列表。我正在处理一个案例,其中不同的数字指的是同一个项目。
在我的示例代码中,“term2”包含代码为“AAAA”和“CCCC”的条目。
df1 = pd.DataFrame(
{
'term' : ['term1','term2','term3','term4','term1','term3','term2'],
'code': ['ZZZZ', 'AAAA','XXXX','QQQQ','ZZZZ','XXXX','CCCC'],
'count':['1','3','1','1','1','1','3']
}
)
df1 = df1[['term'] + df1.columns[:-1].tolist()]
df2 = pd.DataFrame(
{
'name': ['Dan','Sara','Conroy','Steve'],
'rate': ['3','3.5','5.2','3'],
'location': ['FL','OH','NM','NM'],
'code': ['XXXX','BBBB','PPPP','TTTT'],
'allcodes': ['XXXX,YYYY,ZZZZ','AAAA,BBBB,CCCC','PPPP,QQQQ,RRRR','SSSS,TTTT,UUUU']
}
)
df2 = df2[['name','rate','location','code','allcodes']]
pmissnlist = df1['code'].values.tolist()
df3 = df2[df2['allcodes'].str.contains('|'.join(pmissnlist))].reset_index()
df4 = pd.DataFrame(df3['allcodes'].str.split(',').tolist(),
index=df3.code).stack(level=0).reset_index(level=0)
matches = df4[df4[0].isin(df1.code)]
df5 = df3[df3.code.isin(matches.code)]
df5 = df5.drop_duplicates()#drops duplicate rows
df5_temp = df5.set_index(['name','rate','location','code']).allcodes.str.split(',',expand = True)\
.stack().reset_index(4,drop = True).reset_index(name = 'allcodes')
df5 = pd.merge(df1, df5_temp, left_on = 'code', right_on = 'allcodes')
df5 = df5.drop('allcodes', 1).groupby(['code_y','term','count','name','rate','location']).code_x.\
apply(','.join).reset_index().sort_values(by='count', ascending=False)
print(df5)
输出结果为:
code_y term count name rate location code_x
0 BBBB term2 3 Sara 3.5 OH AAAA,CCCC
1 PPPP term4 1 Conroy 5.2 NM QQQQ
2 XXXX term1 1 Dan 3 FL ZZZZ,ZZZZ
3 XXXX term3 1 Dan 3 FL XXXX,XXXX
有两个与Sara关联的term2实例,所以我希望她的数量为6,而不是3.对于每个Dan的行,计数也应为2。如果我正确理解了数据帧,那么这是预期的:数据帧包含满足第一个term2条件的数据。比较第二个实例时,相关数据已存在于数据框中。
如何在df2的“allcode”字段中对多个代码匹配的计数值求和?
编辑:添加所需的结果
code_y term count name rate location code_x
0 BBBB term2 6 Sara 3.5 OH AAAA,CCCC
1 PPPP term4 1 Conroy 5.2 NM QQQQ
2 XXXX term1 2 Dan 3 FL ZZZZ,ZZZZ
3 XXXX term3 2 Dan 3 FL XXXX,XXXX
EDIT2: 问题出在groupby上。
这是df5在输出groupby之前的输出:
term code_x count name rate location code_y allcodes
0 term1 ZZZZ 1 Dan 3 FL XXXX ZZZZ
1 term1 ZZZZ 1 Dan 3 FL XXXX ZZZZ
2 term2 AAAA 3 Sara 3.5 OH BBBB AAAA
3 term3 XXXX 1 Dan 3 FL XXXX XXXX
4 term3 XXXX 1 Dan 3 FL XXXX XXXX
5 term4 QQQQ 1 Conroy 5.2 NM PPPP QQQQ
6 term2 CCCC 2 Sara 3.5 OH BBBB CCCC
7 term6 TTTT 1 Steve 3 NM TTTT TTTT
所以,基本上我希望在groupby之前计算具有相同术语的列(Sara的term2,以及Dan的term3和term4)。
答案 0 :(得分:2)
IIUC,使用str.split
和len
df['count']*=df['code_x'].str.split(',').apply(len)
df
Out[1105]:
code_y term count name rate location code_x
0 BBBB term2 6 Sara 3.5 OH AAAA,CCCC
1 PPPP term4 1 Conroy 5.2 NM QQQQ
2 XXXX term1 2 Dan 3.0 FL ZZZZ,ZZZZ
3 XXXX term3 2 Dan 3.0 FL XXXX,XXXX
编辑:
df.groupby(['code_y','term'],as_index=False).agg({'count':'sum','name':'first','rate':'first','location':'first','code_x':lambda x : ','.join(x),'allcodes':'first'})
Out[1130]:
code_y term count name rate location code_x allcodes
0 BBBB term2 5 Sara 3.5 OH AAAA,CCCC AAAA
1 PPPP term4 1 Conroy 5.2 NM QQQQ QQQQ
2 TTTT term6 1 Steve 3.0 NM TTTT TTTT
3 XXXX term1 2 Dan 3.0 FL ZZZZ,ZZZZ ZZZZ
4 XXXX term3 2 Dan 3.0 FL XXXX,XXXX XXXX
答案 1 :(得分:1)
我创建了一个小函数来获得预期的输出。
def f(x):
return pd.Series(dict(count = x['count'].sum(),
code_x = "%s" % ', '.join(x['code_x'])))
df5=df5.groupby(['code_y','term','name','rate','location'])[['code_x','count']].apply(f).reset_index()
输出
code_y term name rate location code_x count
0 BBBB term2 Sara 3.5 OH AAAA, CCCC 6
1 PPPP term4 Conroy 5.2 NM QQQQ 1
2 XXXX term1 Dan 3 FL ZZZZ, ZZZZ 2
3 XXXX term3 Dan 3 FL XXXX, XXXX 2