Как сгруппировать по двум зависимым столбцам и сгенерировать новый уникальный ключ, используя python pandas или networkx lib? - PullRequest
4 голосов
/ 23 января 2020

Мы пытаемся создать новый идентификационный номер (уникальный ключ) для поиска уникального клиента, используя python pandas или python сетевой график (networkx lib):

Два столбца в зависимости друг от друга ( наоборот), необходимо сгруппировать по обоим столбцам и сгенерировать новый уникальный ключ.

Ниже приведен список примеров данных в python pandas dataframe.

Набор входных данных:

    r_vid   d_ph_nm    d_flg
    DQLA853 6123340277  N
    DQLA851 6999045706  N
    DQLA851 6999340277  Y
    DQLCT41 6999045706  N
    DQLCT41 7123104672  N
    DQLCT41 9123010121  N
    DQLA852 6999290277  N
    DQLA962 6999290277  Y
    DQLC181 6222232026  N
    DQLT381 6222232026  N
    DQLC860 9912332326  N
    DQLC860 9912336579  N

Набор выходных данных:

    r_vid_group        d_ph_nm_group                              new_unique_id
    DQLA851,DQLCT41   6999045706,6999340277,7123104672,9123010121     123
    DQLA852,DQLA962   6999290277                                      124
    DQLA853           6123340277                                      125
    DQLC181,DQLT381   6222232026                                      126
    DQLC860           9912332326,9912336579                           127

Не могли бы вы предложить в python pandas или python pandas сетевой график (networkx lib).

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Вы можете попробовать это:

import networkx as nx

G = nx.from_pandas_edgelist(df, 'r_vid', 'd_ph_nm', create_using=nx.Graph())

# If you want to picture the graph
#fig, ax = plt.subplots(figsize=(15,10))
#nx.draw_networkx(G, ax=ax)

dfgroup = pd.DataFrame()
for n, i in enumerate(nx.connected_components(G)):
    arr = np.array(list(i))
    s = [node in df['r_vid'].tolist() for node in i]
    node_r = arr[s]
    t = [node in df['d_ph_nm'].tolist() for node in i]
    node_d = arr[t]
    df_r = pd.DataFrame({'r_vid_group':[node_r], 
                         'd_ph_num_group':[node_d]},
                        index=[n]) 
    dfgroup = pd.concat([dfgroup,df_r])

dfgroup = dfgroup.rename_axis('new_unique_id').reset_index()

Вывод:

   new_unique_id         r_vid_group                                     d_ph_nm_group
0              0           [DQLA853]                                      [6123340277]
1              1  [DQLA851, DQLCT41]  [7123104672, 9123010121, 6999045706, 6999340277]
2              2  [DQLA852, DQLA962]                                      [6999290277]
3              3  [DQLC181, DQLT381]                                      [6222232026]
4              4           [DQLC860]                          [9912336579, 9912332326]
1 голос
/ 24 января 2020

Вот довольно широкий обходной путь, использующий отдельные элементы в качестве уникальных идентификаторов:

new_ids_simple = {}
new_ids_map = {}
i=0
for d_ph_nm, r_vid in df[['d_ph_nm','r_vid']].values:

    if all([x not in new_ids_map.keys() for x in [d_ph_nm, r_vid]]):
        new_ids_map[d_ph_nm] = i
        new_ids_map[r_vid] = i
        new_ids_simple[i] = {'d_ph_nm':[d_ph_nm],'r_vid':[r_vid]}
        i+=1
    else:
        # retrieving unique value:
        None
        for x in [d_ph_nm, r_vid]:
            if x in new_ids_map.keys():
                new_val = new_ids_map.get(x)
            else:
                new_key = x
        # setting unique value
        new_ids_map[new_key] = new_val
        new_ids_simple[new_val]['d_ph_nm'].append(d_ph_nm)
        new_ids_simple[new_val]['r_vid'].append(r_vid)


map_df = pd.DataFrame.from_dict(new_ids_simple,orient='index')
map_df.index.names = ['ID']
map_df['d_ph_nm'] = map_df['d_ph_nm'].apply(pd.unique)
map_df['r_vid'] = map_df['r_vid'].apply(pd.unique)

# To convert from an array to a string (inside the df)
map_df['r_vid'] = map_df['r_vid'].apply(', '.join)

                                           d_ph_nm             r_vid
ID                                                                  
0                                       6123340277           DQLA853
1   6999045706, 6999340277, 7123104672, 9123010121  DQLA851, DQLCT41
2                                       6999290277  DQLA852, DQLA962
3                                       6222232026  DQLC181, DQLT381
4                           9912332326, 9912336579           DQLC860
...