Условно рассчитывать отношения сотрудник-менеджер - PullRequest
1 голос
/ 09 мая 2019

Я хотел бы суммировать все столбцы has_filed_paperwork для менеджера и всех его сотрудников, и всех сотрудников их сотрудников, и так далее.

Я посмотрел на библиотеку networkx, так как казалось, что я могу это сделать, но я смог только выяснить, как подсчитать всех подчиненных, а не условно.

Я пытался разбить DataFrame на has_filed, а затем не подсчитывал с помощью networkx, но это нарушает отношения, поэтому люди пропадают без вести.

Это примерный фрейм данных.

d = {
        'emp_id':     ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
        'manager_id': ['5', '5', '8', '7', '7', '8', '9', '9', np.NaN, '8'],
        'has_filed':  [False, True, True, True, True, False, False, True, True, True]
    }
    df = pd.DataFrame(d)
    df

Я бы хотел, чтобы выходные данные выглядели примерно так: код ниже - просто кадр данных, который я создал для демонстрации выходных данных.

    do = {
        'emp_id':              ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
        'has_filed_count':     [0, 1, 1, 1, 2, 0, 3, 2, 7, 1],
        'has_not_filed_count': [1, 0, 0, 0, 1, 1, 2, 1, 3, 0]
    }
    df_o = pd.DataFrame(do)
    df_o

1 Ответ

0 голосов
/ 09 мая 2019
import networkx as nx

G = nx.DiGraph()

# Iterate through the dataframe
for index, row in df.iterrows():
    # Create a node with 'has_filled' attribute
    G.add_node(row['emp_id'], has_filled=row['has_filled'])
    # If manager is not np.nan, create an edge to a manager
    if type(row['manager_id']).__name__ == 'str':
        G.add_edge(row['emp_id'], row['manager_id'])

result_dict = {
    'emp_id':              [],
    'has_filled_count':     [],
    'has_not_filled_count': []
}

# Iterate through graph nodes
for n in G.nodes():
    # Get 'has_filled' attribute for all ancestors+current_node
    # We can do it because our graph is a tree, and tree is a subclass of DAG
    counted = [G.nodes[anc]['has_filled'] for anc in nx.ancestors(G, n) | {n}]
    # Fill the dict
    result_dict['emp_id'].append(n)
    result_dict['has_filled_count'].append(counted.count(True))
    result_dict['has_not_filled_count'].append(counted.count(False))

# And convert it to the dataframe
df_o = pd.DataFrame(result_dict)
df_o
    emp_id  has_filled_count    has_not_filled_count
0   1       0                   1
1   5       2                   1
2   2       1                   0
3   3       1                   0
4   8       3                   1
5   4       1                   0
6   7       3                   2
7   6       0                   1
8   9       7                   3
9   10      1                   0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...