为了账号安全,请及时绑定邮箱和手机立即绑定

Pandas 数据框中的分组匹配

Pandas 数据框中的分组匹配

函数式编程 2021-12-21 16:31:03
我有一个有两列的熊猫数据框。第一列代表name该项目,第二列代表它的一些编码为整数的属性。一个项目可以有多个属性。这是一个示例    name                ids0   A                   147 616 8131   B                   51 616 13 8132   C                   7763   D                   51 671 13 813 10924   E                   13 404 492 903 1093有 300 个这样的独特属性编码为整数,然后以id列中的字符串表示。我想要达到的目标:对于每个 id 找到它出现的行。例如,为了检查id13,我将获取行1, 3 and 4。在我们的数据集中与此 ID 对应的所有唯一 ID 是什么?例如,我会说,对于 id13: [51, 616, 813, 671, 1092, 404, 492, 903, 1093]一旦我们为每个 id 分组了行,我如何比较给定的 id 是否在该组中?例如,我想检查 id52是否曾经与 id 一起出现13,如果是,在哪里以及发生了多少次?我一直在考虑这么久,但无法找到一种有效的方法来获得前两个和有效的方法以及 3)的 DS。请帮忙!
查看完整描述

2 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

不使用任何 for 循环的解决方案


import pandas as pd

import numpu as np


df = 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 occurs

def 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 discussion

def 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 together

def 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")


查看完整回答
反对 回复 2021-12-21
?
Qyouu

TA贡献1786条经验 获得超11个赞

这是三个功能的建议:


import pandas as pd

# first we create the data

data = 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'])


查看完整回答
反对 回复 2021-12-21
  • 2 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信