微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CSV 文件到具有 1 和 0 的邻居关系图

如何解决CSV 文件到具有 1 和 0 的邻居关系图

一个包含州及其邻居的 CSV 文件。在 python 中,我想用这个文件创建一个图形。如何将此数据转换为可以显示 1 和 0 连接的二维列表

CSV

邻居
佛罗里达 佐治亚州阿拉巴马州
阿拉巴马州 佛罗里达州、佐治亚州、田纳西州、密西西比州
田纳西州 阿拉巴马州
格鲁吉亚 佛罗里达州阿拉巴马
密西西比州 阿拉巴马州

2D List 喜欢这个,但只有 1 和 0

佛罗里达 阿拉巴马州 田纳西州 格鲁吉亚 密西西比州
佛罗里达 1 1 0 1 0
阿拉巴马州 1 1 1 1 1
田纳西州 0 1 1 0 0
格鲁吉亚 1 1 0 1 0
密西西比州 0 1 0 0 1

解决方法

试试 str.split + explode + str.get_dummies + sum

然后使用 fill_diagonal 添加自我关系:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'Cities': {0: 'Florida',1: 'Alabama',2: 'Tennessee',3: 'Georgia',4: 'Mississippi'},'Neighbors': {0: 'Alabama,Georgia',1: 'Florida,Georgia,Tennessee,Mississippi',2: 'Alabama',3: 'Alabama,Florida',4: 'Alabama'}
})

# split and explode strings into rows convert to dummies then sum 
# to get totals per city
df = (
    df.set_index('Cities')['Neighbors'].str.split(',')
        .explode()
        .str.get_dummies()
        .sum(level=0)
)

# Fill Diagonal to include self relationship as shown in output
np.fill_diagonal(df.values,1)

print(df)

df

             Alabama  Florida  Georgia  Mississippi  Tennessee
Alabama            1        1        1            1          1
Florida            1        1        1            0          0
Georgia            1        1        1            0          0
Mississippi        1        0        0            1          0
Tennessee          1        0        0            0          1

split + explode + crosstab + fill_diagonal

# split and explode strings into rows
df = df.set_index('Cities')['Neighbors'].str.split(',').explode()

# Cross tab to calculate relationship
df = pd.crosstab(df.index,df).rename_axis(None).rename_axis(None,axis=1)

# Fill Diagonal to include self-relationship as shown in output
np.fill_diagonal(df.values,1)

df

             Alabama  Florida  Georgia  Mississippi  Tennessee
Alabama            1        1        1            1          1
Florida            1        1        1            0          0
Georgia            1        1        1            0          0
Mississippi        1        0        0            1          0
Tennessee          1        0        0            0          1

获取一个 numpy 数组:

df.to_numpy()
[[1 1 1 0 0]
 [0 1 1 1 1]
 [1 0 1 0 0]
 [1 1 0 1 0]
 [1 0 0 0 1]]

或列表:

df.to_numpy().tolist()
[[1,1,0],[0,1],[1,1]]
,

如果您使用 Python 处理图形,我强烈推荐使用 NetworkX 包(文档 here)。

它有许多用于操作图表示的工具以及最常见图算法的实现。

例如,假设您的图形以 CSV 格式存储,其中每行的第一个状态后跟其邻居列表:

$ cat data.csv
Florida,Alabama,Georgia
Alabama,Florida,Mississippi
Tennessee,Alabama
Georgia,Florida
Mississippi,Alabama

然后你可以读入它并轻松查看邻接矩阵表示:

>>> import networkx as nx
>>> G = nx.read_adjlist("data.csv",delimiter=",")
>>> A = nx.linalg.graphmatrix.adjacency_matrix(G)
>>> A.todense()
matrix([[0,0]])

邻接矩阵表示的另一种方法是使用字典的字典,它是稀疏的,以相同的方式索引,并且更容易阅读:

>>> nx.convert.to_dict_of_dicts(G,edge_data=1)
{'Florida': {'Alabama': 1,'Georgia': 1},'Alabama': {'Florida': 1,'Georgia': 1,'Tennessee': 1,'Mississippi': 1},'Georgia': {'Florida': 1,'Alabama': 1},'Tennessee': {'Alabama': 1},'Mississippi': {'Alabama': 1}}
,

首先导入pandas并读取数据:

import pandas as pd

file = open('data.csv','r')
data = file.readlines()

“数据”将如下所示:

data

['Florida;Alabama,Georgia\n','Alabama;Florida,Mississippi\n','Tennessee;Alabama\n','Georgia;Alabama,Florida\n','Mississippi;Alabama\n']

将您的数据修正为友好格式:

# creating a list of cities and its neighboors
for i in range(len(data)):
    data[i] = data[i].strip() # to remove '\n'
    data[i] = data[i].split(sep=';') # 'Florida;Alabama,Georgia' > ['Florida','Alabama,Georgia']
    data[i][1] = data[i][1].split(sep=',') # 'Alabama,Georgia' > ['Alabama','Georgia']

你的数据看起来像这样(好多了?):

data

 [['Florida',['Alabama','Georgia']],['Florida','Georgia','Tennessee','Mississippi']],['Tennessee',['Alabama']],['Georgia','Florida']],['Mississippi',['Alabama']]]

然后,创建城市和邻居列表。它将帮助您创建 DataFrame:

# creating a list of cities and neighboors
cities = []
neighboors = []
for d in data:
    cities.append(d[0])
    neighboors.extend(d[1])
neighboors = list(set(neighboors)) # to remove duplicates

列表将如下所示:

print('Cities List:',cities,'\nNeighboors List:',neighboors)

Cities List: ['Florida','Alabama','Mississippi'] 
Neighboors List: ['Mississippi','Florida','Tennessee']

然后,根据'data'创建一个数据框并将nan替换为0或1:

# creating a dataframe with columns and index
df = pd.DataFrame(index=cities,columns=neighboors)

# replace nan to 1 or 0
for d in data:
    for n in d[1]:
        df.loc[d[0],n] = 1
df.fillna(0,inplace=True)

'df' 将如下所示:

result df

希望对你有帮助?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。