统计数据帧之间的公共列值(Python)
我有多张表,如下所示。统计数据帧之间的公共列值(Python),python,pandas,Python,Pandas,我有多张表,如下所示。 共有10个df表,行数范围为1000-25000行。 这些df表是在对它们进行聚类后生成的。因此,行数的差异 df = pd.DataFrame({'id': [1,2,3,4,5], 'segments' : ["a,b,c", "c,a", "d,a,b", "e,g", "a,e,d"]}) ref = pd.DataFrame({'id': [1,4], 'segments' : ["a,b,c", "e,g"]}) 我的目标是确定每个df表中是否存在r
共有10个df表,行数范围为1000-25000行。
这些df表是在对它们进行聚类后生成的。因此,行数的差异
df = pd.DataFrame({'id': [1,2,3,4,5], 'segments' : ["a,b,c", "c,a", "d,a,b", "e,g", "a,e,d"]})
ref = pd.DataFrame({'id': [1,4], 'segments' : ["a,b,c", "e,g"]})
我的目标是确定每个df表中是否存在ref ID如果是,我需要检查每个df表的每一行,并计算有多少段是相同的
我的最终输出如下 到目前为止,我已经确定了如何检查ref ID是否存在
# get the ref id present in df
for index, row in enumerate(df.id):
for index2, row2 in enumerate(ref.id):
if row == row2:
print("ref id present")
print(row,index)
else:
"no ref id"
我已经尝试过使用交集函数。但是我得到了输出0
len(set(df['segments']).intersection(set(ref['segments'])))
我做了研究,但大多数解决方案都涉及单列值,使用merge解决。但是,mine在1列中有多个值我花了2天的时间研究如何检查和计算公共值,并将其全部放在一个循环中,以便在10个df表上执行
我认为需要使用
分割创建集合,然后通过集合进行比较。交叉点
:
segments = [set(x.split(',')) for x in df['segments']]
ref = [set(x.split(',')) for x in ref['segments']]
for i, x in enumerate(ref, 1):
df['ref_{}'.format(i)] = [len(y.intersection(x)) for y in segments]
print (df)
id segments ref_1 ref_2
0 1 a,b,c 3 0
1 2 c,a 2 0
2 3 d,a,b 2 0
3 4 e,g 0 2
4 5 a,e,d 1 1
如果性能很重要,另一种解决方案(O(n)):
for i, x in enumerate(ref, 1):
df['ref_{}'.format(i)] = [len([val for val in x if val in y]) for y in segments]
这应该可以工作df=df[df['segments'].isin(ref['segments'])。groupby('segments',as_index=False)['segments'])。agg(['count'])我需要找到公共值的数量。意思是df=[a,c]和ref id1=[a,g,e],那么输出值应该是1(公共值是a)。你的解决方案需要[a,g,e]和[a,c]。因为它们不完全相同,所以输出为0。啊,所以用逗号分割线段,将其更改为set,然后查找交点。这很好用。非常感谢。@user123-是的,对我来说最难的是理解输出;)不客气!
segments = [set(x.split(',')) for x in df['segments']]
ref = [set(x.split(',')) for x in ref['segments']]
for i, x in enumerate(ref, 1):
df['ref_{}'.format(i)] = [len(y.intersection(x)) for y in segments]
print (df)
id segments ref_1 ref_2
0 1 a,b,c 3 0
1 2 c,a 2 0
2 3 d,a,b 2 0
3 4 e,g 0 2
4 5 a,e,d 1 1
for i, x in enumerate(ref, 1):
df['ref_{}'.format(i)] = [len([val for val in x if val in y]) for y in segments]