猿问

Pandas 数据框中的分组匹配

我有一个有两列的熊猫数据框。第一列代表name该项目,第二列代表它的一些编码为整数的属性。一个项目可以有多个属性。这是一个示例


    name                ids

0   A                   147 616 813

1   B                   51 616 13 813

2   C                   776

3   D                   51 671 13 813 1092

4   E                   13 404 492 903 1093

有 300 个这样的独特属性编码为整数,然后以id列中的字符串表示。我想要达到的目标:

  1. 对于每个 id 找到它出现的行。例如,为了检查id13,我将获取行1, 3 and 4

  2. 在我们的数据集中与此 ID 对应的所有唯一 ID 是什么?例如,我会说,对于 id13: [51, 616, 813, 671, 1092, 404, 492, 903, 1093]

  3. 一旦我们为每个 id 分组了行,我如何比较给定的 id 是否在该组中?例如,我想检查 id52是否曾经与 id 一起出现13,如果是,在哪里以及发生了多少次?

我一直在考虑这么久,但无法找到一种有效的方法来获得前两个和有效的方法以及 3)的 DS。请帮忙!


函数式编程
浏览 139回答 2
2回答

阿晨1998

不使用任何 for 循环的解决方案import pandas as pdimport numpu as npdf = pd.DataFrame({'name':'A B C D E'                   .split(),'ids':['147 616 813','51 616 13 813','776','51 671 13 813 1092','13 404 492 903 1093']})#Every input of i_d to functions in int#to get indexes where id occursdef rows(i_d):    i_d = str(i_d)    pattern1 = "[^0-9]" +i_d+"[^0-9]"    pattern2 = i_d+"[^0-9]"        pattern3 = "[^0-9]" +i_d     mask = df.ids.apply(lambda x: True if (len(re.findall(pattern1,x)) > 0) | (len(re.findall(pattern2,x))) | (len(re.findall(pattern3,x)) > 0) else False)    return df[mask].index.tolist()#to get other ids occuring with the id in discussiondef colleagues(i_d):    i_d = str(i_d)    df.loc[rows(i_d),'temp'] = 1    k =list(set(df.groupby('temp').ids.apply(lambda x: ' '.join(x)).iloc[0].split()))    k.remove(i_d)    df.drop('temp',axis=1,inplace=True)    return k#to get row indexes where 2 ids occur togetherdef third(i_d1,i_d2):    i_d1 = str(i_d1)    i_d2 = str(i_d2)    common_rows = list(np.intersect1d(rows(i_d1),rows(i_d2)))    if len(common_rows) > 0:        return print('Occured together at rows ',common_rows)    else:        return print("Didn't occur together")

Qyouu

这是三个功能的建议:import pandas as pd# first we create the datadata = pd.DataFrame({'name': ['A','B','C','D','E'],                'ids': ['147 616 813','51 616 13 813','776','51 671 13 813 1092','13 404 492 903 1093']})def func1(num, series):    # num must be an int    # series a Pandas series    tx = series.apply(lambda x: True if str(num) in x.split() else False)    output_list = series.index[tx].tolist()    return output_list def func2(num, series):    # num must be an int    # series a Pandas series    series = series.iloc[func1(num, series)]    series = series.apply(lambda x: x.split()).tolist()    output_list = set([item for sublist in series for item in sublist])    output_list.remove(str(num))    return list(output_list)def func3(num1,num2,series):    # num1 must be an int    # num2 must be an int    # series a Pandas series    if str(num1) in func2(num2, series):        num1_index = func1(num1, series)        num2_index = func1(num2, series)        return list(set(num1_index) & set(num2_index))    else:        return 'no match'然后你可以测试它们:func1(13, data['ids'])func2(13, data['ids'])func3(13,51,data['ids'])
随时随地看视频慕课网APP

相关分类

Python
我要回答