Ad

Get Count And Reporting Persons Details

- 1 answer

I have a dataframe with 2 columns: "emp" is the child column and "man" is the parent column. I need to count the total number of children ( direct/indirect) for any given parent.

emp         man
23ank(5*)   213raj(11*)
55man(5*)   213raj(11*)
2shu(1*)    23ank(5*)
7am(3*)     55man(5*)
9shi(0*)    55man(5*)
213raj(11*) 66sam(13*)

The solution I am looking for is if, for instance, I want the details related to 213raj(11*), then:

213raj(11*),23ank(5*),2shu(1*),55man(5*),7am(3*),9shi(0*)

and the total count for 213raj(11*) =5.

If I consider 66sam(13*) then:

66sam(13*),213raj(11*),23ank(5*),2shu(1*),55man(5*),7am(3*),9shi(0*)

and the total count for 66sam(13*) =6

I tried the code below but am not getting the required results:

kv = kvpp[['emp','man']]
kvp = dict(zip(kv.emp,kv.man))

parents = set()
children = {}
for c,p in kvp.items():
    parents.add(p)
    children[c] = p

def ancestors(p):
    return (ancestors(children[p]) if p in children else []) + [p]

pp = []
for k in (set(children.keys()) - parents):
    pp.append('/'.join(ancestors(k)))
Ad

Answer

If I've understood your question correctly, this function should give you the correct answers:

import pandas as pd

df = pd.DataFrame({'emp':['23ank(5*)', '55man(5*)', '2shu(1*)', '7am(3*)', '9shi(0*)', '213raj(11*)'],
                   'man':['213raj(11*)', '213raj(11*)', '23ank(5*)', '55man(5*)', '55man(5*)', '66sam(13*)']})


def count_children(parent):
    total_children = []  # initialise list of children to append to
    direct = df[df['man'] == parent]['emp'].to_list()
    total_children += direct  # add direct children

    indirect = df[df['man'].isin(direct)]['emp'].to_list()
    total_children += indirect  # add indirect children

    # next, add children of indirect children in a loop
    next_indirect = indirect
    while True:
        next_indirect = df[df['man'].isin(next_indirect)]['emp'].to_list()
        if not next_indirect or all(i in total_children for i in next_indirect):
            break
        else:
            total_children = list(set(next_indirect).union(set(total_children)))

    count = len(total_children)
    return pd.DataFrame({'count':count,
                     'children':','.join(total_children)},
                     index=[parent])

count_children('213raj(11*)') -> 5

count_children('66sam(13*)') -> 6

Ad
source: stackoverflow.com
Ad