熊猫数据框中的分组明智匹配

时间:2019-03-29 08:29:54

标签: python python-3.x pandas optimization data-analysis

我有一个熊猫数据框,其中有两列。第一列代表项目的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,请查找其出现的行。例如,为了检查id 13,我将获取行1, 3 and 4
  2. 在我们的数据集中,此ID附带的所有唯一ID是什么?例如,对于ID 13: [51, 616, 813, 671, 1092, 404, 492, 903, 1093]
  3. 一旦每个ID都有分组行,如何比较给定ID是否在该组中?例如,我要检查ID 52是否曾经与ID 13一起发生过,如果是,请问在哪里和多少次?

我已经考虑了很长时间,但是无法提供一种有效的方法来获得前两个,也没有一种有效的方法以及DS可以用于3)。请帮忙!

2 个答案:

答案 0 :(得分:0)

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

sections_prefixes = ['\nI.', '\nII.', '\nIII.', '\nIV.', '\nV.']
end_prefixes = '\n'

index = []

for prefix in sections_prefixes:
    match = re.search(prefix + ' (.*){}'.format(end_prefixes), s)
    index.append(match.group(1).replace(' ', ''))

答案 1 :(得分:0)

以下是这三个功能的建议:

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