data = {
'org_id' :[4,73,6,77,21,36,40,22,21,30,31],
'flag': [['4', '73'],['73'],['6', '77'],['77'],['21'],['36', '36'],['40'],['22', '41'],['21'],['22', '30'],['31', '31']],
'r_id' : [4,4,6,6,20,20,20,22,28,28,28]
}
df = pd.DataFrame.from_dict(data)
df
所需的数据帧如下所示,
data = {
'org_id' :[4,73,6,77,21,36,40,22,21,30,31],
'flag': [['4', '73'],['73'],['6', '77'],['77'],['21'],['36', '36'],['40'],['22', '41'],['21'],['22', '30'],['31', '31']],
'r_id' : [4,4,6,6,20,20,20,22,28,28,28],
'is_foundin_org_id': ['yes','yes','yes','yes','NO','NO','NO','yes','NO','NO','NO']
}
df2 = pd.DataFrame.from_dict(data)
df2
输出数据帧
Out[115]:
org_id flag r_id is_foundin_org_id
0 4 [4, 73] 4 yes
1 73 [73] 4 yes
2 6 [6, 77] 6 yes
3 77 [77] 6 yes
4 21 [21] 20 NO
5 36 [36, 36] 20 NO
6 40 [40] 20 NO
7 22 [22, 41] 22 yes
8 21 [21] 28 NO
9 30 [22, 30] 28 NO
10 31 [31, 31] 28 NO
需要在按r_id分组后识别r_id的分组行中是否存在r_id,例如。当我在org_id的某一行中找到按4分组时,因此我将第4组标记为是,类似地,在org_id列中未找到20,因此将所有20s组标记为否。谢谢。
答案 0 :(得分:3)
IIUC,
df['is_found'] = np.where(df['org_id'].eq(df['r_id']) # check if the ids are equal
.groupby(df['r_id']) # group by r_id
.transform('any'), # if True occurs within the groups
'yes', 'no')
输出:
org_id flag r_id is_found
0 4 [4, 73] 4 yes
1 73 [73] 4 yes
2 6 [6, 77] 6 yes
3 77 [77] 6 yes
4 21 [21] 20 no
5 36 [36, 36] 20 no
6 40 [40] 20 no
7 22 [22, 41] 22 yes
8 21 [21] 28 no
9 30 [22, 30] 28 no
10 31 [31, 31] 28 no
答案 1 :(得分:3)
尝试一下
d = {True: 'Yes', False: 'No'}
df['is_foundin_org_id'] = (df.org_id.eq(df.r_id).groupby(df.r_id)
.transform('max').map(d))
Out[1549]:
org_id flag r_id is_foundin_org_id
0 4 [4, 73] 4 Yes
1 73 [73] 4 Yes
2 6 [6, 77] 6 Yes
3 77 [77] 6 Yes
4 21 [21] 20 No
5 36 [36, 36] 20 No
6 40 [40] 20 No
7 22 [22, 41] 22 Yes
8 21 [21] 28 No
9 30 [22, 30] 28 No
10 31 [31, 31] 28 No
答案 2 :(得分:1)
Numpy
和pandas.factorize
这似乎令人费解。但是我正在使用Numpy
并将所有内容保留为 O(n)
获取数组,因为我将多次使用它们
a = df.r_id.to_numpy()
b = df.org_id.to_numpy()
因子化可以用从零开始的整数来标识每个唯一值。 pandas.factorize
将返回(factorized_integer_representation, unique_values)
的元组。分解的优点在于,我可以使用这些整数作为唯一值数组中的位置来重现原始数组。即使用下面的r[i]
和r
来i
。
我还可以将numpy.unique
与参数return_inverse
一起使用来获取相同的数组,但是 pandas.factorize
不会对唯一值进行排序,是 O(log(n))的订单,我们可以通过不使用来保存该订单。对于更大的数据,pandas.factorize
是赢家。
我将创建一个保存数组,该数组将容纳关于每个唯一值是否满足我们的 any 条件的布尔值。 numpy.logical_or.at
是我们用来查看来自a == b
的任何值是否在True
中指定索引内的i
的功能。
我将在下面的代码后面进行演示。
i, r = pd.factorize(a)
o = np.zeros(len(r), bool)
np.logical_or.at(o, i, a == b)
df.assign(is_found=np.where(o, 'Yes', 'No')[i])
org_id flag r_id is_found
0 4 [4, 73] 4 Yes
1 73 [73] 4 Yes
2 6 [6, 77] 6 Yes
3 77 [77] 6 Yes
4 21 [21] 20 No
5 36 [36, 36] 20 No
6 40 [40] 20 No
7 22 [22, 41] 22 Yes
8 21 [21] 28 No
9 30 [22, 30] 28 No
10 31 [31, 31] 28 No
a == b
array([True, False, True, False, False, False, False, True, False, False, False])
r
是唯一值
r
array([ 4, 6, 20, 22, 28])
i
是索引
i
array([0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 4])
所以r[i]
复制了a
r[i]
array([ 4, 4, 6, 6, 20, 20, 20, 22, 28, 28, 28])
现在,我们从全为False的基数组o
开始,每个唯一值一个
array([False, False, False, False, False])
对于i
中的每个位置,我们检查a == b
中的对应值是否为True
。
# i, a == b -> 0, True <4 == 4>
# 0, False <4 != 73>
# ↓ 1, True <6 == 6>
# ↓ 1, False <6 != 77>
# ↓ ↓ 2, False <20 != 21>
# ↓ ↓ 2, False <20 != 36>
# ↓ ↓ 2, False <20 != 40>
# ↓ ↓ ↓ 3, True <22 == 22>
# ↓ ↓ ↓ ↓ 4, False <28 != 21>
# ↓ ↓ ↓ ↓ 4, False <28 != 30>
# ↓ ↓ ↓ ↓ 4, False <28 != 31>
# At least 1 True ↓ ↓ ↓ ↓ ↓
# o -> [ True, True, False, True, False]
交换Yes
| No
而不是True
| False
# o -> [ True, True, False, True, False]
# np.where(o, 'Yes', 'No') -> [ 'Yes', 'Yes', 'No', 'Yes', 'No']
并用i
对其进行切片,以生成与原始长度相同的数组,并为唯一值数组中的每个对应值提供适当的值。
np.where(o, 'Yes', 'No')[i]
['Yes', 'Yes', 'Yes', 'Yes', 'No', 'No', 'No', 'Yes', 'No', 'No', 'No']