我试图重新设计我的问题,以符合质量标准,并花更多时间试图自己实现结果。
给出两个DataFrame
a = DataFrame({"id" : ["id1"] * 3 + ["id2"] * 3 + ["id3"] * 3,
"left" : [6, 2, 5, 2, 1, 4, 5, 2, 4],
"right" : [1, 3, 4, 6, 5, 3, 6, 3, 2]
})
b = DataFrame({"id" : ["id1"] * 6 + ["id2"] * 6 + ["id3"] * 6,
"left_and_right" : range(1,7) * 3,
"boolen" : [0, 0, 1, 0, 1, 0, 1, 0, 0 , 1, 1, 0, 0, 0, 1, 0, 0, 1]
})
预期结果是
result = DataFrame({"id" : ["id1"] * 3 + ["id2"] * 3 + ["id3"] * 3,
"left" : [6, 2, 5, 2, 1, 4, 5, 2, 4],
"right" : [1, 3, 4, 6, 5, 3, 6, 3, 2],
"NEW": [0, 1, 1, 0, 1, 1, 1, 1, 0]
})
所以我想检查DataFrame b的每一行,如果DataFrame中有一行a aid == b.id然后查找b.left_and_right是否在(==)a.left或者a .rigtht。
如果找到这样的行并且对于a.left或a.right的值,b.boolen为True / 1,则该行中a.NEW的值也应为True / 1。
我希望这个例子比我的话更好地说明了它。
总结一下:我想查找两个数据框中id是否相同的每一行是否b.boolen为真/ 1表示b.left_and_right中的值,如果此值为a.left或在a.right中,a.NEW中的新值也应为TRUE / 1.
我尝试将pd.match()和pd.merge()函数与&组合使用和|运营商但无法达到想要的结果。
前段时间我曾经问过一个非常类似的问题来处理R中的simillar问题(数据是以稍微不同的方式组织的,所以它有点不同)但现在我在python中使用相同的方法失败了。
相关问题:Conditional matching of two lists with multi-column data.frames
由于
答案 0 :(得分:3)
只需使用带&的布尔掩码(和)和| (或):
In [11]: (a.A == b.A) & ((a.B == b.E) | (a.C == b.E)) # they all satisfy this requirement!
Out[11]:
0 True
1 True
2 True
3 True
dtype: bool
In [12]: b.D[(a.A == b.A) & ((a.B == b.E) | (a.C == b.E))]
Out[12]:
0 0
1 1
2 0
3 0
Name: D, dtype: int64
In [13]: a['NEW'] = b.D[(a.A == b.A) & ((a.B == b.E) | (a.C == b.E))]
In [14]: a
Out[14]:
A B C NEW
0 foo 1 4 0
1 goo 2 3 1
2 doo 3 1 0
3 boo 4 2 0
使用略有不同的问题进行更新:
In [21]: merged = pd.merge(a, b, on='id')
In [22]: matching = merged[(merged.left == merged.left_and_right) | (merged.right == merged.left_and_right)]
In [23]: (matching.groupby(['id', 'left', 'right'])['boolen'].sum()).reset_index()
Out[23]:
id left right boolen
0 id1 2 3 1
1 id1 5 4 1
2 id1 6 1 0
3 id2 1 5 2
4 id2 2 6 0
5 id2 4 3 1
6 id3 2 3 1
7 id3 4 2 0
8 id3 5 6 1
注意这里有一个2,所以也许你想关心那些> 0
In [24]: (matching.groupby(['id', 'left', 'right'])['boolen'].sum() > 0).reset_index()
Out[24]:
id left right boolen
0 id1 2 3 True
1 id1 5 4 True
2 id1 6 1 False
3 id2 1 5 True
4 id2 2 6 False
5 id2 4 3 True
6 id3 2 3 True
7 id3 4 2 False
8 id3 5 6 True
您可能希望将boolen列重命名为NEW。