如何按两个依赖列分组并使用 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 中的列进行分组?