Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 获取与同一列下的两个值匹配的记录(查找共享关联)_Python 3.x_Pandas_Pandas Groupby - Fatal编程技术网

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