如何根据存储在另一个数据框中的子字符串和行数过滤此 pandas 数据框?

How can I filter this pandas dataframe based with substrings and row counts stored in another dataframe?

我有一个数据框,其中一列中包含一组人名作为字符串。 然后我还有一个数据框,其中包含一个人名列表(每个人的名字 1 个数据框行)。所描述的示例数据集:

    groupsofpeople = pd.DataFrame({'group':['Genie, Chris, Mike, Dee','Chase, Chris, 
        William S.','Mike, Tim', 'William S., Chris, Tim'], 'rank':[1,2,3,4]})
    people = pd.DataFrame({'name':['Chris','Chase','Ross Rick', 'William S.'], 
        'rowcnt':[30,25,15,25]})

                          group  rank
    0   Genie, Chris, Mike, Dee     1
    1  Chase, Chris, William S.     2
    2                 Mike, Tim     3
    3    William S., Chris, Tim     4

    >>> people
             name  rowcnt
    0       Chris      2
    1       Chase      3
    2   Ross Rick      1
    3  William S.      2

我的目标是遍历 'people' 数据框名称,如果组中有 1 个名称匹配,则定位 groupsofpeople 中的行。额外的警告是,我还想将每一行过滤为仅 return rowcnt 列中的人数。因此,如果 groupsofpeople 数据框有 5 行包含 Chris,则在应用过滤器之前执行此语句,然后在找到子字符串后,只有前 2 行被 returned(作为特定顺序的 groupsofpeople 区域)。

我没有完全掌握列表理解来自行解决这个问题,但我可以告诉你,如果有一种方法可以遍历名称(在 str.contains() 中)以及 rowcnt(在 head() 中):

    founddf = groupsofpeople[groupsofpeople['group'].str.contains('Chris')].head(2)
    upload = pd.concat([upload,founddf],ignore_index=False, sort=False)
    founddf = groupsofpeople[groupsofpeople['group'].str.contains('Chase')].head(3)
    upload = pd.concat([upload,founddf],ignore_index=False, sort=False)
    founddf = groupsofpeople[groupsofpeople['group'].str.contains('Ross Rick')].head(1)
    upload = pd.concat([upload,founddf],ignore_index=False, sort=False)

这是我希望在不对 loop/iterations 进行硬编码的情况下获得的结果:

          group                  rank
       Chase, Chris, William S.     2
       Genie, Chris, Mike, Dee      1
       Chase, Chris, William S.     2

谁能帮我实现这个解决方案?

这是一种根据 people 数据帧

中的 'rowcnt' 值输出每个人的前 n 行的方法
names = set(people.name)
people2 = people.set_index('name')

(groupsofpeople
 .assign(group_list=groupsofpeople['group'].str.split(', ').apply(lambda x: set(x).intersection(names)))
 .explode('group_list')
 .dropna(subset=['group_list'])
 .groupby(['group_list'])
 .apply(lambda d: d.head(people2.loc[d.name, 'rowcnt']))
 .reset_index(drop=True)
 #.drop('group_list', axis=1) #kept here to see groups
)

输出:

                      group  rank  group_list
0  Chase, Chris, William S.     2       Chase
1   Genie, Chris, Mike, Dee     1       Chris
2  Chase, Chris, William S.     2       Chris
3  Chase, Chris, William S.     2  William S.
4    William S., Chris, Tim     4  William S.