Как связать «базу данных списков» с Python? - PullRequest
2 голосов
/ 18 апреля 2020

Это часть более крупной программы, созданной, чтобы помочь переводить римские даты в нашем текущем календаре.

Мне нужно связать своего рода "базу данных списков" (все римские консульства и их даты) как следующая

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 = input("Consulate name: ")
date = date_()
print(name, " was consulate in ", date)

Но делать это вручную - чистое самоубийство (у нас будет около 800 ", если имя в списке []:").

Мои вопросы здесь

1 ° Можно ли так делать? Или я просто делаю что-то очень простое для понимания, но несколько глупое?

2 ° Могу ли я каким-то образом извлечь список Википедии для того, чтобы 800 списков уже были сделаны с именами и датой? назначен? Если нет, я должен сделать это в Excel, а затем найти способ составить списки? Выполнение 800 в Excel будет болезненным, но все же меньше, чем в Python. Я мог бы также попробовать в SPARQL в RDF здесь выбрать только консулов ​​с их именем и датой консульства, но я не знаю, как это работает ...

Спасибо за любые мысли!

Ответы [ 2 ]

2 голосов
/ 18 апреля 2020

Поскольку значения находятся в таблицах, вы можете использовать pandas для чтения страницы и получения таблиц как DataFrames

Но все же могут потребоваться некоторые работы для объединения таблиц и заполнения пустых ячеек. А когда у вас будут все данные, вы сможете хранить их в словаре.

d = {"Name A": 509, "Name B": 509, "Name C": 509, "Name D": 508, "Name E": 508, ...}

и использовать простой

date = d.get(name, None)

Простой код, который получает все таблицы со страницы Википедии

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...

РЕДАКТИРОВАТЬ: Этот код получить все таблицы, объединить их и сохранить в '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')

и позже вы можете читать из файла и искать

Кстати: некоторые имена много раз встречаются в таблице, поэтому я всегда возвращаю список с годами или None (но вместо None он может вернуть пустой список, а затем его всегда можно использовать с for -l oop - даже если список пуст)

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']

Но столбцы, возможно, все еще должны очистить данные перед использованием.

  • код не добавляет таблицу Eastern Roman Consul, в которой есть разные столбцы, но вы можете сохранить all_tables[13] в отдельном файле и использовать в качестве отдельных данных

  • проверка кода в обоих столбцах Consul prior и Consul posterior но вы можете использовать только один из них

  • для некоторых консулов ​​не было года, поэтому я использую .fillna(), чтобы получить значение из строки выше. В основном это строка с текстом «Консульские трибуны», но иногда это может быть другой совет, и этот метод может давать неправильные результаты.

  • в некоторых годах / именах есть добавление, которое добавляет число, например [205] на сегодняшний день / имя и я удаляю его.

1 голос
/ 18 апреля 2020

Если в любом случае у кого-то возникла такая же проблема, как у меня, вот как я решил первую часть (ie структурированный сбор данных из Википедии проще, чем с panda).

В основном он использует преимущества связанных открытых данных. Dbpedia структурирует огромное количество данных из Википедии. Этот структурированный способ может использоваться для запроса с SPARQL. Для меня цель состояла в том, чтобы извлечь имена и даты республиканских консулов. Конечная точка DBpedia - это браузерное решение для выполнения запроса в DBpedia. Код, который я использовал, был

select  ?name ?date

where 

{
?consul a yago:WikicatRomanRepublicanConsuls;
rdfs:label ?name;
dbp:years ?date    
} 

Первая строка - это просто имена двух столбцов, которые будут экспортированы; Где спросить «где» найти информацию, которую мы хотим. ?consul a yago:WikicatRomanRepublicanConsuls - для выбора определенной c «папки» (я не знаю, извините) в базе данных DBpedia, ie здесь все «объекты», содержащие республиканского консула. Эти объекты являются ссылками, содержащими другие свойства (не уверен, что это работает, извините). Так как «? Consul» отсутствует в Select, этот объект (ie ссылки) не будет отображаться в конечном результате (мне все равно, какие ссылки я удалил напрямую). Надеюсь, это достаточно ясно, я все еще пытаюсь понять, как это работает точно. rdfs:label ?name; - запросить соответствующее имя у «объекта», а dbp:years ?date - запросить соответствующую дату.
Затем результаты были экспортированы в csv [имя, дата], а затем импортированы в Excel, что сделало 2 хороших Кульмары легко чистить. Спасибо UninformedUser за идею использования dbpedia btw! И спасибо Furas за другие советы! Теперь мне нужно очистить данные, а затем найти реальную проблему в моем вопросе: ie как сделать эти столбцы в списках пригодными для использования в Python!

...