Pandas 检查是否在数据框中的列列表中找到组id或元素

Pandas 检查是否在数据框中的列列表中找到组id或元素,pandas,dataframe,pandas-groupby,Pandas,Dataframe,Pandas Groupby,所需数据帧如下所示 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

所需数据帧如下所示

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
在按r_id分组后,需要确定r_id是否存在于r_id的分组行中,例如,当在org_id的一行中发现I group by 4时,因此我为组4标记yes,类似地,在org_id列中未找到20,因此我为所有20岁组标记No。谢谢你。

IIUC

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
输出:

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
Numpy
pandas.factorize
这似乎很复杂。但我使用的是
Numpy
并将所有内容O(n)

获取数组,因为我将多次使用它们

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
分解某物用一个以零开始的整数标识每个唯一值
pandas.factorize
将返回
的元组(factorized\u integer\u表示,唯一的\u值)
。因式分解的好处在于,我可以使用这些整数作为唯一值数组中的位置来重现原始数组。即使用下面的
r
i

我也可以使用
numpy.unique
和参数
return\u inverse
来获得相同的数组,但是
pandas.factorize
不会对唯一值进行排序,这是一个O(log(n))的顺序,我们可以通过不使用它来保存。对于较大的数据,
pandas.factorize
是赢家

我将创建一个保留数组,该数组将根据每个唯一值是否满足任何条件来容纳布尔值
numpy.logical_或.at
是我们用来查看
a==b
中的任何值是否
True
i
中的指定索引内

我将在下面的代码之后演示

a = df.r_id.to_numpy()
b = df.org_id.to_numpy()

细节
r
是唯一的值

a == b

array([True, False, True, False, False, False, False, True, False, False, False])

i
是索引

r

array([ 4,  6, 20, 22, 28])

所以
r[i]
复制
a

i

array([0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 4])

现在我们从一个包含所有False的基本数组
o
开始,每个惟一值对应一个

r[i]

array([ 4,  4,  6,  6, 20, 20, 20, 22, 28, 28, 28])
对于
i
中的每个位置,我们检查
a==b
中的对应值是否为
True

array([False, False, False, False, False])
然后使用
i
对其进行切片,以生成一个与原始数组长度相同的数组,并为唯一值数组中的每个对应值提供适当的值

#  o                         -> [    True,     True,    False,     True,    False]
#  np.where(o, 'Yes', 'No')  -> [   'Yes',    'Yes',     'No',    'Yes',     'No']

标记的用途是什么,如果与问题无关,您可以删除它吗?我想知道第一个
r\u id
是否可能是
73
,而不是
4
@ragaelc,IIUC,73可以是well@rafaelc在groupby
r\u id
之后的每个操作,因此该案例将产生两个
no
?@QuangHoang Yea!我的解释和你一样,但是这个
flag
专栏就像你的numpy解决方案一样把我甩了:1+1Thx@AndyL。更新了更多细节。哇,很好的详细解释。我把它标记为我的最爱。竖起大拇指!
#  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]
#  o                         -> [    True,     True,    False,     True,    False]
#  np.where(o, 'Yes', 'No')  -> [   'Yes',    'Yes',     'No',    'Yes',     'No']
np.where(o, 'Yes', 'No')[i]

['Yes', 'Yes', 'Yes', 'Yes', 'No', 'No', 'No', 'Yes', 'No', 'No', 'No']