如何 link 一个 "lists database" 和 Python?
How to link a "lists database" with Python?
这是一个更大的程序的一部分,旨在帮助翻译我们当前日历中的罗马日期。
我需要link一种"lists database"(所有罗马领事馆及其日期)如下
def date_():
if name in list1[Name A, Name B, Name C]:
date = 509
return date
if name in list2[Name D, Name E]:
date = 508
return date
if name in list3[Name F]:
etc...
目的是用户输入一个"Name"然后日期会被赋值给一个变量。然后会在所有列表中搜索这个名字,并赋值给对应的日期。
name = input("Consulate name: ")
date = date_()
print(name, " was consulate in ", date)
但是手动这样做纯粹是自杀(我们会有大约 800 "if name in list[]:")。
我的问题是
1°这样可以吗?还是我只是在做一些很容易理解但有些愚蠢的事情?
2° 我能否以某种方式提取 Wikipedia list 以让 800 个列表已经完成并分配了名称和日期?如果不是,我是否应该在 Excel 中执行此操作,然后找到制作列表的方法?在 Excel 中完成 800 将很痛苦,但仍然比在 Python 中少。
我也可以尝试在 RDF here 中的 SPARQL 中仅选择具有姓名和领事馆日期的领事,但我不知道它是如何工作的...
感谢任何想法!
因为值在 tables 中,所以您可以使用 pandas
读取页面并获得 tables 作为 DataFrames
但它仍然可能需要一些工作来加入 tables 并填充空单元格。当您拥有所有数据时,您可以将它们保存在字典中。
d = {"Name A": 509, "Name B": 509, "Name C": 509, "Name D": 508, "Name E": 508, ...}
并使用简单
date = d.get(name, None)
从维基百科页面
获取所有table的简单代码
import pandas as pd
all_tables = pd.read_html('https://en.wikipedia.org/wiki/List_of_Roman_consuls')
print('number of tables:', len(all_tables))
for number, df in enumerate(all_tables):
print('\n---', number, '---\n')
print(df.head())
结果:
number of tables: 18
--- 0 ---
Ancient Rome
Periods
Roman Kingdom753–509 BC Roman Republic509–27 BC Roman Empire27 BC – AD 395 Principate Dominate WesternAD 395–476 EasternAD 395–1453 Timeline
0 Roman Constitution
1 Constitution of the Kingdom Constitution of th...
2 Precedent and law
3 Roman law Ius Imperium Mos maiorum Collegialit...
4 Assemblies
--- 1 ---
0 ... 3
0 A. = Aulus Ap. = Appius C. = Gaius Cn. = Gnaeu... ... Sex. = Sextus Sp. = Spurius T. = Titus Ti. = T...
[1 rows x 4 columns]
--- 2 ---
Year Consul prior Consul posterior
0 509 L. Junius Brutus L. Tarquinius Collatinus
1 suff. Sp. Lucretius Tricipitinus P. Valerius Poplicola
2 suff. M. Horatius Pulvillus NaN
3 508 P. Valerius Poplicola II T. Lucretius Tricipitinus
4 507 P. Valerius Poplicola III M. Horatius Pulvillus II[18]
--- 3 ---
Year ... Consul posterior
0 500 ... M'. Tullius Longus
1 499 ... C. Veturius Geminus Cicurinus
2 498 ... T. Lartius (Flavus or Rufus) II
3 497 ... M. Minucius Augurinus
4 496 ... T. Verginius Tricostus Caeliomontanus
[5 rows x 3 columns]
--- 4 ---
Year Consul prior Consul posterior
0 400 Consular Tribunes NaN
1 NaN P. Licinius Calvus Esquilinus P. Maelius Capitolinus
2 NaN P. Manlius Vulso Sp. Furius Medullinus
3 NaN L. Titinius Pansa Saccus L. Publilius Philo Vulscus
4 399 Consular Tribunes NaN
--- 5 ---
Year Consul prior Consul posterior
0 300 M. Valerius Maximus Corvus V Q. Appuleius Pansa
1 299 M. Fulvius Paetinus T. Manlius Torquatus
2 suff. NaN M. Valerius Maximus Corvus VI
3 298 L. Cornelius Scipio Barbatus Cn. Fulvius Maximus Centumalus
4 297 Q. Fabius Maximus Rullianus IV P. Decius Mus III
--- 6 ---
Year Consul prior Consul posterior
0 200 P. Sulpicius Galba Maximus II C. Aurelius Cotta
1 199 L. Cornelius Lentulus P. Villius Tappulus
2 198 T. Quinctius Flamininus Sex. Aelius Paetus Catus
3 197 C. Cornelius Cethegus Q. Minucius Rufus
4 196 L. Furius Purpureo M. Claudius Marcellus
--- 7 ---
Year Consul prior Consul posterior
0 100[63] C. Marius VI L. Valerius Flaccus
1 99 M. Antonius A. Postumius Albinus
2 98 Q. Caecilius Metellus Nepos T. Didius
3 97 Cn. Cornelius Lentulus P. Licinius Crassus
4 96 Cn. Domitius Ahenobarbus C. Cassius Longinus
--- 8 ---
Year ... Consul posterior
0 1[77] ... L. Aemilius Paullus (January–June)
1 suff. ... M. Herennius Picens (July–December)
2 2 ... P. Alfenus Varus
3 suff. ... T. Quinctius Crispinus Valerianus
4 3 ... M. Servilius
[5 rows x 3 columns]
--- 9 ---
Year ... Consul posterior
0 101[134] ... Q. Articuleius Paetus II (January–March)
1 suff. ... NaN
2 suff. ... M. Maecius Celer
3 suff. ... ignotus
4 suff.[135] ... L. Julius Marinus Caecilius Simplex
[5 rows x 3 columns]
--- 10 ---
Year ... Consul posterior
0 201 ... M. Nonius Arrius Mucianus
1 202 ... Imp. Caesar M. Aurelius Antoninus Augustus
2 suff.[182] ... C. Cassius Regallianus
3 203 ... P. Septimius Geta II
4 204 ... M. Annius Flavius Libo
[5 rows x 3 columns]
--- 11 ---
Year ... Consul posterior
0 301 ... Virius Nepotianus
1 302 ... C. Galerius Valerius Maximianus Caesar IV
2 303 ... Imp. Caesar M. Aurelius Valerius Maximianus Au...
3 304 ... Imp. Caesar M. Aurelius Valerius Maximianus Au...
4 305 ... C. Galerius Valerius Maximianus Caesar V
[5 rows x 3 columns]
--- 12 ---
Year Consul prior Consul posterior
0 396.0 Flavius Arcadius Augustus IV Flavius Honorius Augustus III
1 397.0 Flavius Caesarius Nonius Atticus
2 398.0 Flavius Eutychianus Flavius Honorius Augustus IV
3 399.0 Eutropius Flavius Mallius Theodorus
4 400.0 Aurelianus Flavius Stilicho
--- 13 ---
Year Eastern Roman Consul
0 535[205] Flavius Belisarius
1 536 Post consulatum Belisarii
2 537 II post consulatum Belisarii
3 538 Flavius Marianus Michaelius Gabrielius Archang...
4 539 Flavius Strategius Apion Strategius Apion
--- 14 ---
vteAncient Rome topics vteAncient Rome topics.1
0 Outline Timeline Outline Timeline
1 Epochs Foundation Kingdom overthrow Republic Empire P...
2 Foundation Kingdom overthrow Republic Foundation Kingdom overthrow Republic
3 Empire Pax Romana Principate Dominate Western Empire ...
4 Constitution History Kingdom Republic Empire Late Empire Se...
--- 15 ---
0 1
0 Foundation Kingdom overthrow Republic Foundation Kingdom overthrow Republic
1 Empire Pax Romana Principate Dominate Western Empire ...
--- 16 ---
0 1
0 Ordinary Consul Censor Praetor Tribune Tribune of the P...
1 Extraordinary Rex Interrex Dictator Magister Equitum Decemvi...
编辑: 此代码获取所有 tables,加入它们并保存在 'roman_consuls.csv'
import pandas as pd
all_tables = pd.read_html('https://en.wikipedia.org/wiki/List_of_Roman_consuls')
df = all_tables[2]
for number in range(3, 13):
df = df.append(all_tables[number])
# remove addnotations - ie. `[205]`
df['Year'] = df['Year'].str.replace('\[\d+\]', '')
df['Consul prior'] = df['Consul prior'].str.replace('\[\d+\]', '')
df['Consul posterior'] = df['Consul posterior'].str.replace('\[\d+\]', '')
# use value from previous rows (mostly from row in text 'Consular Tribunes') - `ffill` means `forward fill`
df['Year'] = df['Year'].fillna(method='ffill')
# TODO: remove rows with text `'Consular Tribunes'`
#df.drop(df['Consul prior'] == 'Consular Tribunes', inplace=True)
# save to file
df.to_csv('roman_consuls.csv')
以后您可以从文件中读取并搜索
顺便说一句:有些名字在 table 中出现了很多次,所以我总是 return 列出年份或 None
(但不是 None
它可以 return 空列表,然后它可以始终与 for
-循环一起使用 - 即使列表为空)
import pandas as pd
# read from file
df = pd.read_csv('roman_consuls.csv')
def date_(name):
mask1 = (df['Consul prior'] == name)
mask2 = (df['Consul posterior'] == name)
#mask1 = (df['Consul prior'].str.contains(name))
#mask2 = (df['Consul posterior'].str.contains(name))
rows = df[ mask1 | mask2 ]
if len(rows) > 0:
return rows['Year'].values #[0]
# it will return `None` if there is no rows
for name in ('M. Valerius Volusus', 'Unknow', 'M. Aemilius Lepidus', 'P. Cornelius Cossus', 'Ap. Claudius Crassus Sabinus Regillensis'):
date = date_(name)
print('name:', name)
print('year:', date)
print('---')
结果
name: M. Valerius Volusus
year: ['505']
---
name: Unknow
year: None
---
name: M. Aemilius Lepidus
year: ['285' '232' '187' '158' '126' '78' '46']
---
name: P. Cornelius Cossus
year: ['415' '408' '395']
---
name: Ap. Claudius Crassus Sabinus Regillensis
year: ['451' '451']
但列在使用前可能仍需要清除数据。
代码不添加 table Eastern Roman Consul
,它有不同的列,但您仍然可以将 all_tables[13]
保存在单独的文件中并用作单独的数据
在 Consul prior
和 Consul posterior
两列中进行代码检查,但您只能使用其中一个
有些领事没有年份,所以我使用 .fillna()
从上面的行中获取值。大多数情况下它是带有文本 'Consular Tribunes' 的行,但有时它可能是其他顾问,这种方法可能会给出错误的结果。
一些 years/names 有添加符号,可以将 [205]
之类的数字添加到 date/name,我将其删除。
如果在任何情况下有人遇到与我相同的问题,这里是我如何解决第一部分的(即以结构化方式从维基百科获取数据比使用熊猫更容易使用)。
基本上它利用了链接开放数据。 Dbpedia 正在以结构化的方式计算来自维基百科的大量数据。这种结构化方式可用于通过 SPARQL 发出请求。对我来说,目标是提取共和党领事的姓名和日期。 DBpedia endpoint 是在 DBpedia 中执行请求的浏览器原生解决方案。
我使用的代码是
select ?name ?date
where
{
?consul a yago:WikicatRomanRepublicanConsuls;
rdfs:label ?name;
dbp:years ?date
}
第一行只是将要导出的两列的名称;
哪里就是问“哪里”才能找到我们想要的信息。
?consul a yago:WikicatRomanRepublicanConsuls
是 select DBpedia 数据库中的一个特定“文件夹”(抱歉,我不知道这个好词),即这里所有包含共和党领事的“对象”。 These objects are links containing other properties(不确定是否有效抱歉)。由于“?consul”不在Select中,这个对象(即链接)不会出现在最终结果中(我不关心链接所以我直接删除了它们)。我希望它足够清楚,我仍在努力理解它是如何精确工作的。
rdfs:label ?name;
就是问“对象”对应的名称,而
dbp:years ?date
是问对应的日期
然后将结果导出为 csv [名称,日期],然后导入 Excel,这使得 2 个漂亮的列易于清理。感谢 UninformedUser 使用 dbpedia btw 的想法!并感谢 Furas 提供的其他提示!现在我需要清理数据,然后找到我的问题的真正问题:即如何使列表中的这些列在 Python !
中可用
这是一个更大的程序的一部分,旨在帮助翻译我们当前日历中的罗马日期。
我需要link一种"lists database"(所有罗马领事馆及其日期)如下
def date_():
if name in list1[Name A, Name B, Name C]:
date = 509
return date
if name in list2[Name D, Name E]:
date = 508
return date
if name in list3[Name F]:
etc...
目的是用户输入一个"Name"然后日期会被赋值给一个变量。然后会在所有列表中搜索这个名字,并赋值给对应的日期。
name = input("Consulate name: ")
date = date_()
print(name, " was consulate in ", date)
但是手动这样做纯粹是自杀(我们会有大约 800 "if name in list[]:")。
我的问题是
1°这样可以吗?还是我只是在做一些很容易理解但有些愚蠢的事情?
2° 我能否以某种方式提取 Wikipedia list 以让 800 个列表已经完成并分配了名称和日期?如果不是,我是否应该在 Excel 中执行此操作,然后找到制作列表的方法?在 Excel 中完成 800 将很痛苦,但仍然比在 Python 中少。 我也可以尝试在 RDF here 中的 SPARQL 中仅选择具有姓名和领事馆日期的领事,但我不知道它是如何工作的...
感谢任何想法!
因为值在 tables 中,所以您可以使用 pandas
读取页面并获得 tables 作为 DataFrames
但它仍然可能需要一些工作来加入 tables 并填充空单元格。当您拥有所有数据时,您可以将它们保存在字典中。
d = {"Name A": 509, "Name B": 509, "Name C": 509, "Name D": 508, "Name E": 508, ...}
并使用简单
date = d.get(name, None)
从维基百科页面
获取所有table的简单代码import pandas as pd
all_tables = pd.read_html('https://en.wikipedia.org/wiki/List_of_Roman_consuls')
print('number of tables:', len(all_tables))
for number, df in enumerate(all_tables):
print('\n---', number, '---\n')
print(df.head())
结果:
number of tables: 18
--- 0 ---
Ancient Rome
Periods
Roman Kingdom753–509 BC Roman Republic509–27 BC Roman Empire27 BC – AD 395 Principate Dominate WesternAD 395–476 EasternAD 395–1453 Timeline
0 Roman Constitution
1 Constitution of the Kingdom Constitution of th...
2 Precedent and law
3 Roman law Ius Imperium Mos maiorum Collegialit...
4 Assemblies
--- 1 ---
0 ... 3
0 A. = Aulus Ap. = Appius C. = Gaius Cn. = Gnaeu... ... Sex. = Sextus Sp. = Spurius T. = Titus Ti. = T...
[1 rows x 4 columns]
--- 2 ---
Year Consul prior Consul posterior
0 509 L. Junius Brutus L. Tarquinius Collatinus
1 suff. Sp. Lucretius Tricipitinus P. Valerius Poplicola
2 suff. M. Horatius Pulvillus NaN
3 508 P. Valerius Poplicola II T. Lucretius Tricipitinus
4 507 P. Valerius Poplicola III M. Horatius Pulvillus II[18]
--- 3 ---
Year ... Consul posterior
0 500 ... M'. Tullius Longus
1 499 ... C. Veturius Geminus Cicurinus
2 498 ... T. Lartius (Flavus or Rufus) II
3 497 ... M. Minucius Augurinus
4 496 ... T. Verginius Tricostus Caeliomontanus
[5 rows x 3 columns]
--- 4 ---
Year Consul prior Consul posterior
0 400 Consular Tribunes NaN
1 NaN P. Licinius Calvus Esquilinus P. Maelius Capitolinus
2 NaN P. Manlius Vulso Sp. Furius Medullinus
3 NaN L. Titinius Pansa Saccus L. Publilius Philo Vulscus
4 399 Consular Tribunes NaN
--- 5 ---
Year Consul prior Consul posterior
0 300 M. Valerius Maximus Corvus V Q. Appuleius Pansa
1 299 M. Fulvius Paetinus T. Manlius Torquatus
2 suff. NaN M. Valerius Maximus Corvus VI
3 298 L. Cornelius Scipio Barbatus Cn. Fulvius Maximus Centumalus
4 297 Q. Fabius Maximus Rullianus IV P. Decius Mus III
--- 6 ---
Year Consul prior Consul posterior
0 200 P. Sulpicius Galba Maximus II C. Aurelius Cotta
1 199 L. Cornelius Lentulus P. Villius Tappulus
2 198 T. Quinctius Flamininus Sex. Aelius Paetus Catus
3 197 C. Cornelius Cethegus Q. Minucius Rufus
4 196 L. Furius Purpureo M. Claudius Marcellus
--- 7 ---
Year Consul prior Consul posterior
0 100[63] C. Marius VI L. Valerius Flaccus
1 99 M. Antonius A. Postumius Albinus
2 98 Q. Caecilius Metellus Nepos T. Didius
3 97 Cn. Cornelius Lentulus P. Licinius Crassus
4 96 Cn. Domitius Ahenobarbus C. Cassius Longinus
--- 8 ---
Year ... Consul posterior
0 1[77] ... L. Aemilius Paullus (January–June)
1 suff. ... M. Herennius Picens (July–December)
2 2 ... P. Alfenus Varus
3 suff. ... T. Quinctius Crispinus Valerianus
4 3 ... M. Servilius
[5 rows x 3 columns]
--- 9 ---
Year ... Consul posterior
0 101[134] ... Q. Articuleius Paetus II (January–March)
1 suff. ... NaN
2 suff. ... M. Maecius Celer
3 suff. ... ignotus
4 suff.[135] ... L. Julius Marinus Caecilius Simplex
[5 rows x 3 columns]
--- 10 ---
Year ... Consul posterior
0 201 ... M. Nonius Arrius Mucianus
1 202 ... Imp. Caesar M. Aurelius Antoninus Augustus
2 suff.[182] ... C. Cassius Regallianus
3 203 ... P. Septimius Geta II
4 204 ... M. Annius Flavius Libo
[5 rows x 3 columns]
--- 11 ---
Year ... Consul posterior
0 301 ... Virius Nepotianus
1 302 ... C. Galerius Valerius Maximianus Caesar IV
2 303 ... Imp. Caesar M. Aurelius Valerius Maximianus Au...
3 304 ... Imp. Caesar M. Aurelius Valerius Maximianus Au...
4 305 ... C. Galerius Valerius Maximianus Caesar V
[5 rows x 3 columns]
--- 12 ---
Year Consul prior Consul posterior
0 396.0 Flavius Arcadius Augustus IV Flavius Honorius Augustus III
1 397.0 Flavius Caesarius Nonius Atticus
2 398.0 Flavius Eutychianus Flavius Honorius Augustus IV
3 399.0 Eutropius Flavius Mallius Theodorus
4 400.0 Aurelianus Flavius Stilicho
--- 13 ---
Year Eastern Roman Consul
0 535[205] Flavius Belisarius
1 536 Post consulatum Belisarii
2 537 II post consulatum Belisarii
3 538 Flavius Marianus Michaelius Gabrielius Archang...
4 539 Flavius Strategius Apion Strategius Apion
--- 14 ---
vteAncient Rome topics vteAncient Rome topics.1
0 Outline Timeline Outline Timeline
1 Epochs Foundation Kingdom overthrow Republic Empire P...
2 Foundation Kingdom overthrow Republic Foundation Kingdom overthrow Republic
3 Empire Pax Romana Principate Dominate Western Empire ...
4 Constitution History Kingdom Republic Empire Late Empire Se...
--- 15 ---
0 1
0 Foundation Kingdom overthrow Republic Foundation Kingdom overthrow Republic
1 Empire Pax Romana Principate Dominate Western Empire ...
--- 16 ---
0 1
0 Ordinary Consul Censor Praetor Tribune Tribune of the P...
1 Extraordinary Rex Interrex Dictator Magister Equitum Decemvi...
编辑: 此代码获取所有 tables,加入它们并保存在 'roman_consuls.csv'
import pandas as pd
all_tables = pd.read_html('https://en.wikipedia.org/wiki/List_of_Roman_consuls')
df = all_tables[2]
for number in range(3, 13):
df = df.append(all_tables[number])
# remove addnotations - ie. `[205]`
df['Year'] = df['Year'].str.replace('\[\d+\]', '')
df['Consul prior'] = df['Consul prior'].str.replace('\[\d+\]', '')
df['Consul posterior'] = df['Consul posterior'].str.replace('\[\d+\]', '')
# use value from previous rows (mostly from row in text 'Consular Tribunes') - `ffill` means `forward fill`
df['Year'] = df['Year'].fillna(method='ffill')
# TODO: remove rows with text `'Consular Tribunes'`
#df.drop(df['Consul prior'] == 'Consular Tribunes', inplace=True)
# save to file
df.to_csv('roman_consuls.csv')
以后您可以从文件中读取并搜索
顺便说一句:有些名字在 table 中出现了很多次,所以我总是 return 列出年份或 None
(但不是 None
它可以 return 空列表,然后它可以始终与 for
-循环一起使用 - 即使列表为空)
import pandas as pd
# read from file
df = pd.read_csv('roman_consuls.csv')
def date_(name):
mask1 = (df['Consul prior'] == name)
mask2 = (df['Consul posterior'] == name)
#mask1 = (df['Consul prior'].str.contains(name))
#mask2 = (df['Consul posterior'].str.contains(name))
rows = df[ mask1 | mask2 ]
if len(rows) > 0:
return rows['Year'].values #[0]
# it will return `None` if there is no rows
for name in ('M. Valerius Volusus', 'Unknow', 'M. Aemilius Lepidus', 'P. Cornelius Cossus', 'Ap. Claudius Crassus Sabinus Regillensis'):
date = date_(name)
print('name:', name)
print('year:', date)
print('---')
结果
name: M. Valerius Volusus
year: ['505']
---
name: Unknow
year: None
---
name: M. Aemilius Lepidus
year: ['285' '232' '187' '158' '126' '78' '46']
---
name: P. Cornelius Cossus
year: ['415' '408' '395']
---
name: Ap. Claudius Crassus Sabinus Regillensis
year: ['451' '451']
但列在使用前可能仍需要清除数据。
代码不添加 table
Eastern Roman Consul
,它有不同的列,但您仍然可以将all_tables[13]
保存在单独的文件中并用作单独的数据在
Consul prior
和Consul posterior
两列中进行代码检查,但您只能使用其中一个有些领事没有年份,所以我使用
.fillna()
从上面的行中获取值。大多数情况下它是带有文本 'Consular Tribunes' 的行,但有时它可能是其他顾问,这种方法可能会给出错误的结果。一些 years/names 有添加符号,可以将
[205]
之类的数字添加到 date/name,我将其删除。
如果在任何情况下有人遇到与我相同的问题,这里是我如何解决第一部分的(即以结构化方式从维基百科获取数据比使用熊猫更容易使用)。
基本上它利用了链接开放数据。 Dbpedia 正在以结构化的方式计算来自维基百科的大量数据。这种结构化方式可用于通过 SPARQL 发出请求。对我来说,目标是提取共和党领事的姓名和日期。 DBpedia endpoint 是在 DBpedia 中执行请求的浏览器原生解决方案。
我使用的代码是
select ?name ?date
where
{
?consul a yago:WikicatRomanRepublicanConsuls;
rdfs:label ?name;
dbp:years ?date
}
第一行只是将要导出的两列的名称; 哪里就是问“哪里”才能找到我们想要的信息。
?consul a yago:WikicatRomanRepublicanConsuls
是 select DBpedia 数据库中的一个特定“文件夹”(抱歉,我不知道这个好词),即这里所有包含共和党领事的“对象”。 These objects are links containing other properties(不确定是否有效抱歉)。由于“?consul”不在Select中,这个对象(即链接)不会出现在最终结果中(我不关心链接所以我直接删除了它们)。我希望它足够清楚,我仍在努力理解它是如何精确工作的。
rdfs:label ?name;
就是问“对象”对应的名称,而
dbp:years ?date
是问对应的日期
然后将结果导出为 csv [名称,日期],然后导入 Excel,这使得 2 个漂亮的列易于清理。感谢 UninformedUser 使用 dbpedia btw 的想法!并感谢 Furas 提供的其他提示!现在我需要清理数据,然后找到我的问题的真正问题:即如何使列表中的这些列在 Python !
中可用