Python 3.x 获取与同一列下的两个值匹配的记录(查找共享关联)
如何查询数据帧以获取与一列下的不同值关联的记录?它本质上是一个联合查询:Python 3.x 获取与同一列下的两个值匹配的记录(查找共享关联),python-3.x,pandas,pandas-groupby,Python 3.x,Pandas,Pandas Groupby,如何查询数据帧以获取与一列下的不同值关联的记录?它本质上是一个联合查询: data = {"id": ["a", "a", "a", "b", "b", "c", "c", "d", "e", "f", "f", "f"], "x": [1, 2, 3, 1, 3, 5, 1, 7, 2, 4, 9, 11], "y": [1985, 1986, 1987, 1985, 1987, 1990, 1985, 1994, 1985, 1989, 1993, 1993]
data = {"id": ["a", "a", "a", "b", "b", "c", "c", "d", "e", "f", "f", "f"],
"x": [1, 2, 3, 1, 3, 5, 1, 7, 2, 4, 9, 11],
"y": [1985, 1986, 1987, 1985, 1987, 1990, 1985, 1994, 1985, 1989, 1993, 1993]}
df = pd.DataFrame(data)
print(df)
id x y
0 a 1 1985
1 a 2 1986
2 a 3 1987
3 b 1 1985
4 b 3 1987
5 c 5 1990
6 c 1 1985
7 d 7 1994
8 e 2 1985
9 f 4 1989
10 f 9 1993
11 f 11 1993
鉴于上述数据,我希望得到一个函数fid1,id2,year=None,它将查找与id1和id2都关联的x。所以f'a',b'将返回一个对应于{x:[1,3],y:[1985,1987]}的数据帧
x y
0 1 1985
1 3 1987
因为x=1和x=3都与“a”和“b”相关联
理想情况下,我希望能够以允许通过“y”值进行过滤的方式来实现这一点。此外,数据帧相当大,这是一个经常运行的实用函数,因此效率很重要。我曾想过使用不同的ID查询两次并合并:
In [15]: pd.merge(df.query('id=="a"'), df.query('id=="b"'), on='x')
Out[15]:
id_x x y_x id_y y_y
0 a 1 1985 b 1985
1 a 3 1987 b 1987
但我觉得这不是最优雅、最有效的方式。IIUC,这应该能满足您的主要需求
def f(x,y):
g = df.groupby('id')
g1 = g["x"].get_group(x).to_list()
g2 = g["x"].get_group(y).to_list()
return [val for val in g1 if val in g2]
f('a', 'b')
输出
[1,3]
如果需要的输出是数据帧,下面的代码应该可以工作
def f(x,y):
g = df.groupby('id')
if g.get_group(x).shape[0] >= g.get_group(y).shape[0]:
res = g.get_group(x)[['x','y']].merge(g.get_group(y)[['x','y']], on=['x','y'],how = 'inner')
else:
res = g.get_group(y)[['x','y']].merge(g.get_group(x)[['x','y']], on=['x','y'],how = 'inner')
return res
f('a', 'b')
输出
我修改了一点moys的答案并添加了perf。 你可以做: data=pd.DataFrame{id:[a,a,a,b,b,c,c,d,e,f,f,f], x:[1,2,3,1,3,5,1,7,2,4,9,11], y:[1985、1986、1987、1985、1987、1990、1985、1994、1985、1989、1993、1993]} def finderida,idb,年份=无: g=数据。分组方式为'id' g1=setg[x]。获取组ID g2=setg[x]。获取组IDB 如果年份: return data.loc[data.x.ising1&g2&data.id.isin[ida,idb]&data.y==year] 其他: return data.loc[data.x.ising1&g2&data.id.isin[ida,idb] 它吸引 4.42 ms±36.9µs/回路7次运行的平均值±标准偏差,每次100个回路 相比之下,您当前的代码 10.2 ms±123µs/回路7次运行的平均值±标准偏差,每次100个回路 更新后的moys代码绘制: 每个回路10.6 ms±60.3µs,平均值±标准偏差为7次运行,每个回路100次
谢谢你的回答。我写预期结果的方式一定让你有点困惑。我不需要列表本身。这会改变你的答案吗?将groupby'id'与其余部分分开以避免重复运行是否有意义,因为此函数将运行数十万次是的,如果元素h您希望分组不会更改,它肯定会提高性能。我还编辑了一篇文章,因为我在get组中犯了一个非动态的小错误。感谢澄清和更新,检查API文档后的一个快速注释,如果性能很重要,在groupby中设置sort=False也应该是好的。
x y
0 1 1985
1 3 1987