我正在使用的数据如下:

Name RefSecondary     RefMain
test  2               3
bet   3               4
get   1               2
set   null            1
net   3               5

我做了一个非常简单的查询,它在数据框中查找值的存在并构建层次结构
sys_role = 'sample.xlsx'
df = pd.read_excel(sys_role,na_filter = False).apply(lambda x: x.astype(str).str.strip())
for i in range(count):
    for j in range(count):
        if df.iloc[i]['RefMain'] == df.iloc[j]['RefSecondary']:
            df.iloc[j, df.columns.get_loc('Name')] = "/".join([df.iloc[i]['Name'],df.iloc[j]['Name']])
    j = j+1
i = i+1

我得到的结果如下:
   Result          RefMain
0  get/test           3
1  test/bet           4
2  set/get            2
3  set                1
4  test/net           5

这真的很慢,而且逻辑也不能完美运行。有没有办法可以更快地完成这项工作?

逻辑需要如下:



结果数据框应如下所示:
   Result            RefMain
0  set/get/test          3
1  set/get/test/bet      4
2  set/get               2
3  set                   1
4  set/get/test/net      5

最佳答案

这听起来像是一个图形问题。您可以尝试 networkx 如下:

df = df.fillna(-1)

# create a graph
G = nx.DiGraph()

# add reference as edges
G.add_edges_from(zip(df['RefMain'],df['RefSecondary'] ))

# rename the nodes accordingly
G = nx.relabel_nodes(G, mapping=df.set_index('RefMain')['Name'].to_dict())


# merge the path list to the dataframe
df = df.merge(pd.DataFrame(nx.shortest_path(G)).T['null'],
              left_on='Name',
              right_index=True)

# new column:
df['Path'] = df['null'].apply(lambda x: '/'.join(x[-2::-1]) )

输出:
   Name RefSecondary RefMain                         null              Path
0  test            2       3       [test, get, set, null]      set/get/test
1   bet            3       4  [bet, test, get, set, null]  set/get/test/bet
2   get            1       2             [get, set, null]           set/get
3   set         null       1                  [set, null]               set
4   net            3       5  [net, test, get, set, null]  set/get/test/net

关于python - 使用 Pandas 中的两列创建层次结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58022512/

10-12 21:40