我有一个公司数据表,将子公司与母公司链接起来,如屏幕截图左侧的表所示。我需要将数据转换到屏幕截图右侧的表格中。这需要跟踪表的两列并在各行之间建立链接。
到目前为止,我唯一尝试过的就是递归地将表与自身连接起来..但我认为这里某种树结构会更有意义吗? IE。创建一个以“最终母公司”为主干的所有关联公司的分支?
这些概念对我来说是新的,所以感谢任何意见
图结构可以满足您的需要。 将节点作为映射添加到母公司,然后构建关系链。 这是与您的图像类似的数据示例。
import pandas as pd
df = pd.DataFrame({
'Subsidiary': ['B', 'C', 'D', 'E', '2', '3'],
'Parent': ['A', 'B', 'C', 'B', '1', '2']
})
下面是处理构建亲缘链以及将数据重新格式化为宽数据框架的数据结构。
class SubsidiaryTree:
def __init__(self):
self.node_to_parent = {}
def add_edge(self, subsidiary, parent):
self.node_to_parent[subsidiary] = parent
self.node_to_parent.setdefault(parent, None)
def build_decendents(self):
chains = []
for sub, parent in self.node_to_parent.items():
if parent is None:
continue
chain = [sub, parent]
while parent is not None:
parent = self.node_to_parent[parent]
if parent is not None:
chain.append(parent)
chains.append(chain)
return chains
def build_wide_df(self):
data = []
for i, chain in enumerate(self.build_decendents()):
first = chain.pop(0)
last = chain.pop()
data.append([i, 'subsidiary', first])
data.extend([[i, f'intermidiate-{j}', x] for j, x in enumerate(chain, 1)])
data.append([i, 'parent', last])
df_long = pd.DataFrame(data, columns=['ix', 'relation', 'company'])
p = df_long.pivot(columns='relation', index='ix', values='company').fillna('')
cols = set(p.columns).difference(['parent', 'subsidiary'])
return p[['subsidiary', *sorted(cols), 'parent']]
使用树结构:
st = SubsidiaryTree()
for _, (s, p) in df.iterrows():
st.add_edge(s, p)
st.build_wide_df()
# returns:
relation subsidiary intermidiate-1 intermidiate-2 parent
ix
0 B A
1 C B A
2 D C B A
3 E B A
4 2 1
5 3 2 1