pandas 我怎样才能把节点相关的配偶在一个家庭树生成器程序彼此相邻?

3z6pesqy  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(70)

我写了一段代码,用pandas和graphviz从一个csv文件中生成一个家谱。
| ID| S|名字|姓氏|DOB|国防部|父亲ID| MotherID|配偶ID|出生地|工作|
| --|--|--|--|--|--|--|--|--|--|--|
| JoS1| M|约翰|S| 1111 | 2222 |||MaS1|印度|工作-1|
| MaS1| F|玛丽|S| 1112 ||||JoS1|印度|工作-2|
| JaS| M|雅各布|S| 1113 ||JoS1| MaS1| KeS|印度|工作-3|
| Jos 2| M|乔|S| 1114 | 2225 |JoS1| MaS1| AnS|印度|工作-4|
| MaS2| F|梅西|D| 1115 ||JoS1| MaS1|和|印度|工作-5|
| KeS| F|基莎|S| 1116 ||||JaS|印度|工作-6|
| 和|M|安迪|D| 1117 ||||MaS2|印度|工作-7|
| AnS| F|安娜|S| 1118 ||||Jos 2|印度|工作-8|
| MiS| M|迈克|S| 1119 ||JaS| KeS||印度||
| SAS| M|山姆|S| 1120 ||JaS| KeS||印度||
| MaS3| F|马特|S| 2345 ||Jos 2| AnS||印度||
代码:

from graphviz import Digraph
import pandas as pd
import numpy as np

rawdf = pd.read_csv('/content/drive/MyDrive/ftdata.csv', keep_default_na=False)  ## Change file path
el1 = rawdf[['ID','MotherID','SpouseID']]
el2 = rawdf[['ID','FatherID','SpouseID']]
el1.columns = ['Child', 'ParentID','SpouseID']
el2.columns = el1.columns
el = pd.concat([el1, el2])
el.replace('', np.nan, regex=True, inplace = True)
t = pd.DataFrame({'tmp':['no_entry'+str(i) for i in range(el.shape[0])]})
el['ParentID'].fillna(t['tmp'], inplace=True)
el['SpouseID'].fillna(t['tmp'], inplace=True)
df = el.merge(rawdf, left_index=True, right_index=True, how='left')
df['name'] = df[df.columns[4:6]].apply(lambda x: ' '.join(x.dropna().astype(str)),axis=1)
df = df.drop(['Child','FatherID', 'ID', 'First name', 'Last name'], axis=1)
df = df[['ID', 'name', 'S', 'DoB', 'DoD', 'Place of birth', 'Job', 'ParentID']]
#df

f = Digraph('neato', format='jpg', encoding='utf8', filename='testfile', node_attr={'style': 'filled'},  graph_attr={"concentrate": "true", "splines":"ortho"})
f.attr('node', shape='box')
for index, row in df.iterrows():
    f.node(row['ID'],
           label=
             str(row['name'])
              + '\n' +
             str(row['Job'])
             + '\n'+
             str(row['DoB'])
             + '\n' +
             str(row['Place of birth'])
             + '\n†' +
             str(row['DoD']),
           _attributes={'color':'lightpink' if row['S']=='F' else 'lightblue'if row['S']=='M' else 'lightgray'})
for index, row in df.iterrows():
    f.edge(str(row["ParentID"]), str(row["ID"]), label='')
f.view()

字符串
结果:
x1c 0d1x的数据
现在,我想使用集群或组将配偶彼此相邻,但找不到方法来做到这一点。所以,我需要帮助来弄清楚如何解决这个问题。

4nkexdtk

4nkexdtk1#

我找到了解决方案,并能够使用下面给出的代码将这些夫妇聚集在一起:

# Check if the node has a spouse
      if str(row['SpouseID']) != '':
          spouse_id = str(row['SpouseID'])

          # Check if the spouse cluster exists, if not create one
          if spouse_id not in spouse_clusters:
              spouse_clusters[spouse_id] = Digraph('cluster_' + spouse_id)
              spouse_clusters[spouse_id].attr(label='Couple', color='lightgreen', style='filled')

          # Add the node to the spouse cluster
          spouse_clusters[spouse_id].node(node_id, label=node_label, color=node_color)
      else:
          # Add nodes without spouses directly to the main Digraph
          f.node(node_id, label=node_label, color=node_color)

  # Add nodes and clusters to the main Digraph
  for cluster_id, cluster in spouse_clusters.items():
      f.subgraph(cluster)

字符串
这段代码是在创建节点之后使用for循环创建节点的部分中添加的。在for循环之前还创建了一个字典'spouse_clusters'。这将添加彼此配偶的节点作为字典的值,并将它们作为子图添加到主有向图。

**注意:**这确实需要更改数据的SpouseID字段中的值,以便配偶双方具有相同的SpouseID。这是通过将配偶名字的前2个字母用作SpouseID来实现的。例如,John S -玛丽S --> JoMa

相关问题