N:::만지작 거리기

N_16. 파이썬으로 RDF 생성하기

joyHong 2021. 9. 8. 22:59
MakeTriple 쥬피터노트북으로 작성된 원본 및 대상 데이터는
https://github.com/joyhong85/rdf_python 에서 확인할 수 있습니다.
RDF Data 생성

RDF 형태의 데이터를 생성한다.

작성자 : 허홍수
e-mail : su4620@gmail.com
blog : http://joyhong.tistory.com

CSV 형태의 데이터를 RDF 형태로 변환하기

데이터 확인

원본 형태의 데이터를 바로 확인할 수도 있지만 여기서는 판다스를 활용하여 null값 등을 확인하도록 한다.

  • 전처리가 잘 되어 있다면 1.1, 1.2 과정을 스킵하고 바로 2번 과정을 수행해도 된다.
In [1]:
import pandas as pd
import numpy as np

df = pd.read_csv('./hospital.csv', header=2)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 74364 entries, 0 to 74363
Data columns (total 17 columns):
 #   Column                  Non-Null Count  Dtype  
---  ------                  --------------  -----  
 0   uri                     74364 non-null  int64  
 1   foaf:page               74364 non-null  object 
 2   rdfs:label              74364 non-null  object 
 3   dcterms:subject         74364 non-null  int64  
 4   Unnamed: 4              74364 non-null  object 
 5   dcterms:subject.1       74364 non-null  int64  
 6   Unnamed: 6              74364 non-null  object 
 7   dcterms:subject.2       74364 non-null  int64  
 8   Unnamed: 8              74364 non-null  object 
 9   schema:postalCode       74364 non-null  int64  
 10  schema:address          74364 non-null  object 
 11  schema:telephone        74055 non-null  object 
 12  foaf:homepage           9097 non-null   object 
 13  my:openedDate           74348 non-null  object 
 14  my:totalNumberOfDoctor  74364 non-null  int64  
 15  schema:longitude        70914 non-null  float64
 16  schema:latitude         70914 non-null  float64
dtypes: float64(2), int64(6), object(9)
memory usage: 9.6+ MB
In [2]:
df.count(axis=0)
Out[2]:
uri                       74364
foaf:page                 74364
rdfs:label                74364
dcterms:subject           74364
Unnamed: 4                74364
dcterms:subject.1         74364
Unnamed: 6                74364
dcterms:subject.2         74364
Unnamed: 8                74364
schema:postalCode         74364
schema:address            74364
schema:telephone          74055
foaf:homepage              9097
my:openedDate             74348
my:totalNumberOfDoctor    74364
schema:longitude          70914
schema:latitude           70914
dtype: int64

null 값이 있는 열 번호 찾기

In [3]:
series = df.isnull().sum(axis=0)
np.where((series > 0).tolist())[0]
Out[3]:
array([11, 12, 13, 15, 16])

11, 12, 13, 15, 16 번 value 값을 처리할 때 null 체크를 해야한다.

CSV 파일 그대로 읽어 RDF로 변환

그래프 생성

In [4]:
from rdflib import Graph, Literal, RDF, URIRef, Namespace
from rdflib.namespace import FOAF, XSD, RDF, RDFS, SKOS, DCTERMS
from tqdm import tqdm


# 그래프 생성
g = Graph()

# namespace 바인딩
RS = Namespace('http://joyhong.tistory.com/resource/')
ONT = Namespace('http://joyhong.tistory.com/ontology/')
SCHEMA = Namespace("http://schema.org/")
g.bind("rs", RS)
g.bind("ont", ONT)
g.bind("schema", SCHEMA)
g.bind("foaf", FOAF)
g.bind("skos", SKOS)
g.bind("dcterms", DCTERMS)

URI 유효성 검사 모듈 생성

RDFLib 에서 URIRef()로 리소스 생성시 유효하지 않은 스트링으로 생성시 시리얼라이즈 되지 않기 때문에 검사를 수행하여야 한다.

In [5]:
_invalid_uri_chars = '<>" {}|\\^`'


def _is_valid_uri(uri):
    for c in _invalid_uri_chars:
        if c in uri:
            return False
    return True

매핑 설정

In [6]:
from dateutil.parser import parse

def makeTripleForHospital(row):
    subject = URIRef(RS+'h_'+row[0])
    geo = URIRef(RS+'geo_h'+row[0])
    g.add((subject, RDF.type, URIRef(SCHEMA+'Hospital')))
    g.add((subject, FOAF.page, URIRef('http://www.hira.or.kr/re/diag/getDiagAmtInfo.do?ykiho='+row[1])))
    g.add((subject, DCTERMS.identifier, Literal(row[1])))
    g.add((subject, RDFS.label, Literal(row[2])))
    if row[11] != '':
        g.add((subject, URIRef(SCHEMA+'telephone'), Literal(row[11])))
    if row[12] != '' and row[12] != 'http://' and _is_valid_uri(row[12]):
        if not row[12].startswith('http'):
            g.add((subject, FOAF.homepage, URIRef('http://'+row[12])))
        else:
            g.add((subject, FOAF.homepage, URIRef(row[12])))
    if row[13] != '':
        if '-00-' in row[13]:
            row[13] = row[13].replace('-00-','-01-')
        g.add((subject, URIRef(ONT+'openedDate'), Literal(parse(row[13]).date())))
    g.add((subject, URIRef(ONT+'totalNumberOfDoctor'), Literal(row[14])))

    #위치
    g.add((subject, URIRef(SCHEMA+'geo'), geo))
    g.add((geo, URIRef(SCHEMA+'postalCode'), Literal(row[9])))
    g.add((geo, URIRef(SCHEMA+'address'), Literal(row[10])))
    if row[15] != '':
        g.add((geo, URIRef(SCHEMA+'longitude'), Literal(row[15])))
    if row[16] != '':
        g.add((geo, URIRef(SCHEMA+'latitude'), Literal(row[16])))
    
    #종별 구분
    g.add((subject, DCTERMS.subject, URIRef(RS+'cat_'+row[3])))
    g.add((URIRef(RS+'cat_'+row[3]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'cat_'+row[3]), RDFS.label, Literal(row[4])))
    g.add((URIRef(RS+'cat_'+row[3]), SKOS.prefLabel, Literal(row[4], lang='ko')))
    g.add((URIRef(RS+'cat_'+row[3]), DCTERMS.identifier, Literal(row[3])))
    
    #시도
    g.add((subject, DCTERMS.subject, URIRef(RS+'rg_'+row[5])))
    g.add((URIRef(RS+'rg_'+row[5]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'rg_'+row[5]), RDFS.label, Literal(row[6])))
    g.add((URIRef(RS+'rg_'+row[5]), SKOS.prefLabel, Literal(row[6], lang='ko')))
    g.add((URIRef(RS+'rg_'+row[5]), DCTERMS.identifier, Literal(row[5])))
    g.add((URIRef(RS+'rg_'+row[5]), SKOS.narrower, URIRef(RS+'rg_'+row[7])))
    g.add((URIRef(RS+'rg_'+row[7]), SKOS.broader, URIRef(RS+'rg_'+row[5])))
    
    #시군구
    g.add((subject, DCTERMS.subject, URIRef(RS+'rg_'+row[7])))
    g.add((URIRef(RS+'rg_'+row[7]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'rg_'+row[7]), RDFS.label, Literal(row[8])))
    g.add((URIRef(RS+'rg_'+row[7]), SKOS.prefLabel, Literal(row[8], lang='ko')))
    g.add((URIRef(RS+'rg_'+row[7]), DCTERMS.identifier, Literal(row[7])))

csv 파일 로딩 및 변환 실행

In [7]:
import csv


data =  open('./hospital.csv', 'r', encoding='utf-8-sig')
rows = csv.reader(data, delimiter=',')

for row in tqdm(list(rows)[3:]):
    makeTripleForHospital(row)

data.close()
100%|██████████| 74364/74364 [00:57<00:00, 1288.85it/s]

파일로 저장

In [8]:
g.serialize(destination='./hospital.ttl', format='turtle')
print("Finished..")
Finished..

Pandas DataFrame 으로부터 RDF 변환

데이터 확인을 위해 dataframe으로 불러 들인 데이터를 활용하여 변환하도록 한다.

데이터 전처리

In [9]:
df
Out[9]:
uri foaf:page rdfs:label dcterms:subject Unnamed: 4 dcterms:subject.1 Unnamed: 6 dcterms:subject.2 Unnamed: 8 schema:postalCode schema:address schema:telephone foaf:homepage my:openedDate my:totalNumberOfDoctor schema:longitude schema:latitude
0 1 JDQ4MTYyMiM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 가톨릭대학교인천성모병원 1 상급종합 220000 인천 220003 인천부평구 21431 인천광역시 부평구 동수로 56 (부평동) 032-1544-9004 http://www.cmcism.or.kr/ 1981.8.6 324 126.724899 37.484831
1 2 JDQ4MTYyMiM1MSMkMSMkNCMkODkkMzgxMzUxIzExIyQxIy... 강릉아산병원 1 상급종합 320000 강원 320100 강릉시 25440 강원도 강릉시 사천면 방동길 38 () 033-610-3114 http://www.gnah.co.kr 1996.7.30 203 128.857841 37.818433
2 3 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 강북삼성병원 1 상급종합 110000 서울 110016 종로구 3181 서울특별시 종로구 새문안로 29 (평동) 02-2001-2001 http://www.kbsmc.co.kr 1979.3.24 403 126.967750 37.568408
3 4 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 건국대학교병원 1 상급종합 110000 서울 110023 광진구 5030 서울특별시 광진구 능동로 120-1 (화양동) 1588-1533 http://www.kuh.ac.kr 1982.11.16 442 127.071828 37.540376
4 5 JDQ4MTYyMiM4MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 경북대학교병원 1 상급종합 230000 대구 230006 대구중구 41944 대구광역시 중구 동덕로 130 (삼덕동2가, 경북대학교병원) 053-200-5114 http://knumc.knu.ac.kr 1910.9.7 487 128.604125 35.866774
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
74359 74360 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxOTYxIzUxIyQxIy... 힘내라한의원 93 한의원 110000 서울 110003 강서구 7526 서울특별시 강서구 화곡로 429 토피아 401호 (가양동) 02-6952-8277 NaN 2017.12.13 1 126.855061 37.561526
74360 74361 JDU4MTI3MSM1MSMkMSMkMCMkMTMkNDgxMzUxIzMxIyQxIy... 힘찬걸음한의원 93 한의원 310000 경기 311901 고양덕양구 10500 경기도 고양시 덕양구 화신로260번길 64 삼진빌딩 4층 401호 (화정동) 031-979-5077 NaN 2019.1.28 1 126.833383 37.633475
74361 74362 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxMzUxIzUxIyQxIy... 힘찬마디한의원 93 한의원 110000 서울 110002 강동구 5329 서울특별시 강동구 천호대로 1027 3층 (천호동) 02-401-7713 NaN 2012.12.17 1 127.126386 37.538123
74362 74363 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkMzgxNzAyIzUxIyQxIy... 힘찬세상경희한의원 93 한의원 110000 서울 110014 용산구 4376 서울특별시 용산구 한강대로 109 (한강로2가, 용성비즈텔) 02-793-2080 http://www.himhani.com 2009.2.24 1 126.968167 37.530005
74363 74364 JDQ4MTg4MSM1MSMkMiMkOCMkMDAkMzgxMzUxIzExIyQyIy... 읻다의원 31 의원 110000 서울 110001 강남구 6012 서울특별시 강남구 도산대로 509 에스디바이오센서 3층 (청담동) 02-3442-7588 NaN NaN 1 NaN NaN

74364 rows × 17 columns

In [10]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 74364 entries, 0 to 74363
Data columns (total 17 columns):
 #   Column                  Non-Null Count  Dtype  
---  ------                  --------------  -----  
 0   uri                     74364 non-null  int64  
 1   foaf:page               74364 non-null  object 
 2   rdfs:label              74364 non-null  object 
 3   dcterms:subject         74364 non-null  int64  
 4   Unnamed: 4              74364 non-null  object 
 5   dcterms:subject.1       74364 non-null  int64  
 6   Unnamed: 6              74364 non-null  object 
 7   dcterms:subject.2       74364 non-null  int64  
 8   Unnamed: 8              74364 non-null  object 
 9   schema:postalCode       74364 non-null  int64  
 10  schema:address          74364 non-null  object 
 11  schema:telephone        74055 non-null  object 
 12  foaf:homepage           9097 non-null   object 
 13  my:openedDate           74348 non-null  object 
 14  my:totalNumberOfDoctor  74364 non-null  int64  
 15  schema:longitude        70914 non-null  float64
 16  schema:latitude         70914 non-null  float64
dtypes: float64(2), int64(6), object(9)
memory usage: 9.6+ MB
In [11]:
df= df.astype(str)
In [12]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 74364 entries, 0 to 74363
Data columns (total 17 columns):
 #   Column                  Non-Null Count  Dtype 
---  ------                  --------------  ----- 
 0   uri                     74364 non-null  object
 1   foaf:page               74364 non-null  object
 2   rdfs:label              74364 non-null  object
 3   dcterms:subject         74364 non-null  object
 4   Unnamed: 4              74364 non-null  object
 5   dcterms:subject.1       74364 non-null  object
 6   Unnamed: 6              74364 non-null  object
 7   dcterms:subject.2       74364 non-null  object
 8   Unnamed: 8              74364 non-null  object
 9   schema:postalCode       74364 non-null  object
 10  schema:address          74364 non-null  object
 11  schema:telephone        74364 non-null  object
 12  foaf:homepage           74364 non-null  object
 13  my:openedDate           74364 non-null  object
 14  my:totalNumberOfDoctor  74364 non-null  object
 15  schema:longitude        74364 non-null  object
 16  schema:latitude         74364 non-null  object
dtypes: object(17)
memory usage: 9.6+ MB
In [13]:
# 컬렴명 변경
df.columns = list(range(len(df.columns)))
In [14]:
# 문자형으로 강제변환하였기에 NaN 값이 nan으로 변경되어 이를 ''로 처리
df.replace(['None', 'nan'], '', inplace=True)
df
Out[14]:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 JDQ4MTYyMiM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 가톨릭대학교인천성모병원 1 상급종합 220000 인천 220003 인천부평구 21431 인천광역시 부평구 동수로 56 (부평동) 032-1544-9004 http://www.cmcism.or.kr/ 1981.8.6 324 126.7248987 37.4848309
1 2 JDQ4MTYyMiM1MSMkMSMkNCMkODkkMzgxMzUxIzExIyQxIy... 강릉아산병원 1 상급종합 320000 강원 320100 강릉시 25440 강원도 강릉시 사천면 방동길 38 () 033-610-3114 http://www.gnah.co.kr 1996.7.30 203 128.8578411 37.8184325
2 3 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 강북삼성병원 1 상급종합 110000 서울 110016 종로구 3181 서울특별시 종로구 새문안로 29 (평동) 02-2001-2001 http://www.kbsmc.co.kr 1979.3.24 403 126.96775 37.5684083
3 4 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 건국대학교병원 1 상급종합 110000 서울 110023 광진구 5030 서울특별시 광진구 능동로 120-1 (화양동) 1588-1533 http://www.kuh.ac.kr 1982.11.16 442 127.0718276 37.5403764
4 5 JDQ4MTYyMiM4MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 경북대학교병원 1 상급종합 230000 대구 230006 대구중구 41944 대구광역시 중구 동덕로 130 (삼덕동2가, 경북대학교병원) 053-200-5114 http://knumc.knu.ac.kr 1910.9.7 487 128.604125 35.866774
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
74359 74360 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxOTYxIzUxIyQxIy... 힘내라한의원 93 한의원 110000 서울 110003 강서구 7526 서울특별시 강서구 화곡로 429 토피아 401호 (가양동) 02-6952-8277 2017.12.13 1 126.8550614 37.5615258
74360 74361 JDU4MTI3MSM1MSMkMSMkMCMkMTMkNDgxMzUxIzMxIyQxIy... 힘찬걸음한의원 93 한의원 310000 경기 311901 고양덕양구 10500 경기도 고양시 덕양구 화신로260번길 64 삼진빌딩 4층 401호 (화정동) 031-979-5077 2019.1.28 1 126.8333826 37.6334749
74361 74362 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxMzUxIzUxIyQxIy... 힘찬마디한의원 93 한의원 110000 서울 110002 강동구 5329 서울특별시 강동구 천호대로 1027 3층 (천호동) 02-401-7713 2012.12.17 1 127.1263862 37.5381231
74362 74363 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkMzgxNzAyIzUxIyQxIy... 힘찬세상경희한의원 93 한의원 110000 서울 110014 용산구 4376 서울특별시 용산구 한강대로 109 (한강로2가, 용성비즈텔) 02-793-2080 http://www.himhani.com 2009.2.24 1 126.9681669 37.5300048
74363 74364 JDQ4MTg4MSM1MSMkMiMkOCMkMDAkMzgxMzUxIzExIyQyIy... 읻다의원 31 의원 110000 서울 110001 강남구 6012 서울특별시 강남구 도산대로 509 에스디바이오센서 3층 (청담동) 02-3442-7588 1

74364 rows × 17 columns

In [15]:
# 13번 컬럼을 date형으로 변환

from dateutil.parser import parse

df[13] = df[13].map(lambda x: parse(x.replace('-00-','-01-')).date() if x!='' else x)
In [16]:
df
Out[16]:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 JDQ4MTYyMiM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 가톨릭대학교인천성모병원 1 상급종합 220000 인천 220003 인천부평구 21431 인천광역시 부평구 동수로 56 (부평동) 032-1544-9004 http://www.cmcism.or.kr/ 1981-08-06 324 126.7248987 37.4848309
1 2 JDQ4MTYyMiM1MSMkMSMkNCMkODkkMzgxMzUxIzExIyQxIy... 강릉아산병원 1 상급종합 320000 강원 320100 강릉시 25440 강원도 강릉시 사천면 방동길 38 () 033-610-3114 http://www.gnah.co.kr 1996-07-30 203 128.8578411 37.8184325
2 3 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 강북삼성병원 1 상급종합 110000 서울 110016 종로구 3181 서울특별시 종로구 새문안로 29 (평동) 02-2001-2001 http://www.kbsmc.co.kr 1979-03-24 403 126.96775 37.5684083
3 4 JDQ4MTg4MSM1MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 건국대학교병원 1 상급종합 110000 서울 110023 광진구 5030 서울특별시 광진구 능동로 120-1 (화양동) 1588-1533 http://www.kuh.ac.kr 1982-11-16 442 127.0718276 37.5403764
4 5 JDQ4MTYyMiM4MSMkMSMkMCMkODkkMzgxMzUxIzExIyQxIy... 경북대학교병원 1 상급종합 230000 대구 230006 대구중구 41944 대구광역시 중구 동덕로 130 (삼덕동2가, 경북대학교병원) 053-200-5114 http://knumc.knu.ac.kr 1910-09-07 487 128.604125 35.866774
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
74359 74360 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxOTYxIzUxIyQxIy... 힘내라한의원 93 한의원 110000 서울 110003 강서구 7526 서울특별시 강서구 화곡로 429 토피아 401호 (가양동) 02-6952-8277 2017-12-13 1 126.8550614 37.5615258
74360 74361 JDU4MTI3MSM1MSMkMSMkMCMkMTMkNDgxMzUxIzMxIyQxIy... 힘찬걸음한의원 93 한의원 310000 경기 311901 고양덕양구 10500 경기도 고양시 덕양구 화신로260번길 64 삼진빌딩 4층 401호 (화정동) 031-979-5077 2019-01-28 1 126.8333826 37.6334749
74361 74362 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkNDgxMzUxIzUxIyQxIy... 힘찬마디한의원 93 한의원 110000 서울 110002 강동구 5329 서울특별시 강동구 천호대로 1027 3층 (천호동) 02-401-7713 2012-12-17 1 127.1263862 37.5381231
74362 74363 JDQ4MTg4MSM1MSMkMSMkNCMkMTMkMzgxNzAyIzUxIyQxIy... 힘찬세상경희한의원 93 한의원 110000 서울 110014 용산구 4376 서울특별시 용산구 한강대로 109 (한강로2가, 용성비즈텔) 02-793-2080 http://www.himhani.com 2009-02-24 1 126.9681669 37.5300048
74363 74364 JDQ4MTg4MSM1MSMkMiMkOCMkMDAkMzgxMzUxIzExIyQyIy... 읻다의원 31 의원 110000 서울 110001 강남구 6012 서울특별시 강남구 도산대로 509 에스디바이오센서 3층 (청담동) 02-3442-7588 1

74364 rows × 17 columns

그래프 생성

In [17]:
from rdflib import Graph, Literal, RDF, URIRef, Namespace
from rdflib.namespace import FOAF, XSD, RDF, RDFS, SKOS, DCTERMS
from tqdm import tqdm


# 그래프 생성
g = Graph()

# namespace 바인딩
RS = Namespace('http://joyhong.tistory.com/resource/')
ONT = Namespace('http://joyhong.tistory.com/ontology/')
SCHEMA = Namespace("http://schema.org/")
g.bind("rs", RS)
g.bind("ont", ONT)
g.bind("schema", SCHEMA)
g.bind("foaf", FOAF)
g.bind("skos", SKOS)
g.bind("dcterms", DCTERMS)

URI 유효성 검사 모듈 생성

In [18]:
_invalid_uri_chars = '<>" {}|\\^`'


def _is_valid_uri(uri):
    for c in _invalid_uri_chars:
        if c in uri:
            return False
    return True

매핑설정(pandas dataframe 활용)

In [19]:
def makeTripleForHospitalByDataFrame(row):
    subject = URIRef(RS+'h_'+row[0])
    geo = URIRef(RS+'geo_h'+row[0])
    g.add((subject, RDF.type, URIRef(SCHEMA+'Hospital')))
    g.add((subject, FOAF.page, URIRef('http://www.hira.or.kr/re/diag/getDiagAmtInfo.do?ykiho='+row[1])))
    g.add((subject, DCTERMS.identifier, Literal(row[1])))
    g.add((subject, RDFS.label, Literal(row[2])))
    if row[11] != '':
        g.add((subject, URIRef(SCHEMA+'telephone'), Literal(row[11])))
    if row[12] != ''  and row[12] != 'http://' and _is_valid_uri(row[12]):
        if not row[12].startswith('http'):
            g.add((subject, FOAF.homepage, URIRef('http://'+row[12])))
        else:
            g.add((subject, FOAF.homepage, URIRef(row[12])))
    if row[13] != '':
        g.add((subject, URIRef(ONT+'openedDate'), Literal(row[13])))
    g.add((subject, URIRef(ONT+'totalNumberOfDoctor'), Literal(row[14])))

    #위치
    g.add((subject, URIRef(SCHEMA+'geo'), geo))
    g.add((geo, URIRef(SCHEMA+'postalCode'), Literal(row[9])))
    g.add((geo, URIRef(SCHEMA+'address'), Literal(row[10])))
    if row[15] != '':
        g.add((geo, URIRef(SCHEMA+'longitude'), Literal(row[15])))
    if row[16] != '':
        g.add((geo, URIRef(SCHEMA+'latitude'), Literal(row[16])))
    
    #종별 구분
    g.add((subject, DCTERMS.subject, URIRef(RS+'cat_'+row[3])))
    g.add((URIRef(RS+'cat_'+row[3]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'cat_'+row[3]), RDFS.label, Literal(row[4])))
    g.add((URIRef(RS+'cat_'+row[3]), SKOS.prefLabel, Literal(row[4], lang='ko')))
    g.add((URIRef(RS+'cat_'+row[3]), DCTERMS.identifier, Literal(row[3])))
    
    #시도
    g.add((subject, DCTERMS.subject, URIRef(RS+'rg_'+row[5])))
    g.add((URIRef(RS+'rg_'+row[5]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'rg_'+row[5]), RDFS.label, Literal(row[6])))
    g.add((URIRef(RS+'rg_'+row[5]), SKOS.prefLabel, Literal(row[6], lang='ko')))
    g.add((URIRef(RS+'rg_'+row[5]), DCTERMS.identifier, Literal(row[5])))
    g.add((URIRef(RS+'rg_'+row[5]), SKOS.narrower, URIRef(RS+'rg_'+row[7])))
    g.add((URIRef(RS+'rg_'+row[7]), SKOS.broader, URIRef(RS+'rg_'+row[5])))
    
    #시군구
    g.add((subject, DCTERMS.subject, URIRef(RS+'rg_'+row[7])))
    g.add((URIRef(RS+'rg_'+row[7]), RDF.type, URIRef(SKOS.Concept)))
    g.add((URIRef(RS+'rg_'+row[7]), RDFS.label, Literal(row[8])))
    g.add((URIRef(RS+'rg_'+row[7]), SKOS.prefLabel, Literal(row[8], lang='ko')))
    g.add((URIRef(RS+'rg_'+row[7]), DCTERMS.identifier, Literal(row[7])))

변환 실행

In [20]:
for value in tqdm(df.values):
#     print(value[0] ,'\t', value[1])
    makeTripleForHospitalByDataFrame(value)
100%|██████████| 74364/74364 [00:52<00:00, 1412.48it/s]

파일로 저장

In [21]:
g.serialize(destination='./hospital_df.ttl', format='turtle')
print("Finished..")
Finished..

Finish