如何按两个依赖列分组并使用 python pandas 或 networkx lib 生成新的唯一键?

Posted

技术标签:

【中文标题】如何按两个依赖列分组并使用 python pandas 或 networkx lib 生成新的唯一键?【英文标题】:How to group by two dependent columns and generate new unique key using python pandas or networkx lib? 【发布时间】:2020-05-09 21:25:02 【问题描述】:

我们正在尝试使用 python pandas 或 python 网络图(networkx lib)创建新的识别号(唯一键)以查找唯一客户:

两列相互依赖(反之亦然),需要按两列分组并生成一个新的唯一键。

以下是 python pandas 数据框中的示例数据列表。

输入数据集:

    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)中提出建议。

【问题讨论】:

从输入到输出的逻辑是什么?按颜色分组? @luigigi 在图网络中的逻辑是connected components。 【参考方案1】:

你可以试试这个:

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]

【讨论】:

from_pandas_edgelist 是做什么的? 它从 pandas 数据框中获取列,并使用源节点和目标节点创建边。 谢谢你 -- @Scott Boston 我面临以下问题:可能是我的服务器有不同的 networkx api 错误:AttributeError: module 'networkx' has no attribute 'from_pandas_edgelist' @SrinivasK 我正在使用 Networkx 2.... 在 networkx 1 中,函数名称为 from_panda_dataframe @SrinivasK Here 是 API 更改的文档。【参考方案2】:

这是一个使用单个项目作为唯一标识符的非常广泛的解决方法:

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

【讨论】:

谢谢! @Yaakov Bressler 它工作正常!!我想从结果中删除数组大括号([]),并且需要将最终结果存储到带有管道分隔符的 csv 文件中。 您可以使用 apply 函数将每个数组连接到逗号分隔的字符串中。 能否请您提供更多关于将数组转换为字符串值的详细信息,包括单引号 '' 逗号分隔值。 谢谢@Yaakov Bressler,它工作正常。我已经为 d_ph_nm 列转换了浮点数据类型。浮点型数组列表转换成字符串数组列表:map_df['d_ph_nm'] = [','.join(map(str, l)) for l in map_df['d_ph_nm']] 很高兴听到! @SrinivasK - 如果您认为我的回答有用,请考虑给它一个赞成票? :)

以上是关于如何按两个依赖列分组并使用 python pandas 或 networkx lib 生成新的唯一键?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python,如何按小时对 Dataframe 中的列进行分组?

如何使用电子表格中的两个不同列制作按图分组的条形图?

如何按列分组,然后在python中的组内重新排序列

text 按变量分组数据并计算其他列#python的统计数据

Python:如何按一列分组行并按另一列选择一行?

如何按id python按一列顺序对两列进行分组[重复]