[PYTHON] Lassen Sie uns automatisch Mitarbeiterinformationen wie das Durchschnittsgehalt aus den von EDINET (5/10) veröffentlichten XBRL-Daten extrahieren.

Im 5. Beitrag des Adventskalenders werde ich versuchen, die gewünschten Informationen aus den von der EDINET-API erfassten XBRL-Daten zu extrahieren. Dieses Mal habe ich versucht, das Durchschnittsgehalt und das Durchschnittsalter von Unternehmen zu ermitteln, die häufig bei der Jobsuche anzutreffen sind.

(Das Programm in diesem Artikel wird ohne Gewähr bereitgestellt. XBRL Japan übernimmt unabhängig von der Ursache die Verantwortung für alle Nachteile oder Probleme, die durch die Verwendung dieses Programms entstehen können. Ich werde es nicht ertragen.)

1. Extrahieren Sie bestimmte Informationen aus XBRL-Daten

1.1 Programmübersicht

Dies ist ein Python-Sprachprogramm, das die von der EDINET-API erfasste Zip-Datei (einschließlich XBRL-Daten) dekomprimiert und analysiert, Informationen wie das Gehalt aus dem Wertpapierbericht extrahiert und die erforderlichen Informationen dann als CSV ausgibt. (Alle Codes sind in "3. Quellcode" aufgeführt.) Die aus den XBRL-Daten zu extrahierenden Elemente sind in der folgenden Tabelle aufgeführt.

Artikel                                        In XBRL definierter Elementname                                                     Akquisitionsbeispiel                                    
EDINETCODE EDINETCodeDEI E00004
Name der Firma FilerNameInJapaneseDEI Kaneko Seedling Co., Ltd.
Durchschnittliches Jahresgehalt (Yen) AverageAnnualSalaryInformationAboutReportingCompanyInformationAboutEmployees 5,554,933
Durchschnittliche Dienstjahre (Jahre) AverageLengthOfServiceYearsInformationAboutReportingCompanyInformationAboutEmployees 13.0
Durchschnittliche Dienstjahre (Monat) AverageLengthOfServiceMonthsInformationAboutReportingCompanyInformationAboutEmployees - -
Durchschnittsalter (Jahre) AverageAgeYearsInformationAboutReportingCompanyInformationAboutEmployees 42.2
Durchschnittsalter (Monat) AverageAgeMonthsInformationAboutReportingCompanyInformationAboutEmployees - -
Anzahl der Mitarbeiter (Personen) NumberOfEmployees 625

Andere charakteristische Punkte werden unten beschrieben. ○ Verwenden Sie die EDINET-Codeliste, um die Branche des Unternehmens zu identifizieren ○ Es entspricht nicht dem Erwerb des "einzigartigen Erweiterungselements" des Unternehmens ○ Für die XBRL-Analyse wurde ein OSS-Parser namens "Arelle" verwendet. ○ Wenn es eine durchschnittliche Dienstzeit (Monat) und ein durchschnittliches Alter (Monat) gibt, "jährliche Umrechnung" (auf die zweite Dezimalstelle gerundet).

1.2 Vorbereitung

Bitte führen Sie die folgenden Aktionen aus, bevor Sie das Programm ausführen. Darüber hinaus müssen andere Bibliotheken im Voraus installiert werden. Ändern Sie je nach Ausführungsumgebung die Codierungs- und Pfadspezifikationsmethode entsprechend.

1.2.1 Vorbereitung der XBRL-Daten

Verwenden Sie "Lassen Sie uns die in XBRL beschriebenen Daten finden", "Lassen Sie uns die in XBRL beschriebenen Daten sammeln" usw., um die Zip-Datei (einschließlich XBRL-Daten) von EDINET herunterzuladen. Das durchschnittliche Jahresgehalt (Yen) und andere Posten sind neu hinzugefügt Posten auf EDINET, also vorerst 2019 Laden Sie die nach dem 1. April veröffentlichten XBRL-Daten herunter.

1.2.2 XBRL-Parser installieren

Installieren Sie den XBRL-Parser mit dem Namen Arelle. Wenn Arelle eine Instanz lädt, analysiert es den DTS-Satz einschließlich externer Taxonomieinformationen. Daher eignet es sich für die Verwendung erweiterter XBRL-Daten. Wenn Sie jedoch nur Instanzen verwenden, dauert die Verarbeitung einige Zeit. Ersetzen Sie sie daher durch die OSS-XML-Bibliothek oder den Parser, den Sie entwickeln. ..

Der Qiita-Artikel enthält auch Informationen zur Installation von Arelle und anderen in der Entwicklung befindlichen Parsern. Einige davon werde ich hier auflisten. ・ XBRL-Analyse, die nicht bei Null beginnt (Verwendung von Arelle)

1.2.3 EDINET-Codeliste vorbereiten

Sie können es nach dem Übergang zur Registerkarte [Download] der EDINET-Site von der EDINET-Codeliste unten auf der Seite herunterladen. Diese Liste ist mit "EDINET CODE and Industry" verknüpft. Mit dieser Liste können Sie daher auch die Art des Geschäfts des Unternehmens erwerben. スクリーンショット 2019-12-01 20.34.47.png

1.2.4 Bestimmen des Speicher- / Dekomprimierungs- / Ausgabeordners

○ Entscheiden Sie sich für einen Speicherordner, um die heruntergeladene EDINET-Codeliste zu lesen. edinetcodedlinfo_filepath = 'C://Users//xxx//Desktop//xbrlReport//EdinetcodeDlInfo.csv'

○ Lassen Sie uns den Ordner festlegen, in dem die von der EDINET-API erfasste Zip-Datei gespeichert werden soll. zip_dir = 'C://Users//xxx//Desktop//xbrlReport//SR//'

○ Legen Sie den Ordner- und Dateinamen für die Ausgabe der CSV fest. employee_frame.to_csv("C://Users//xxx//Desktop//xbrlReport//xbrl_qiita.csv", encoding='cp932')

1.3 Ausführungsergebnis

Entpacken Sie die von der EDINET-API erhaltene Zip-Datei und rufen Sie die Liste der Instanzdateien (Erweiterung .xbrl) im platzierten PublicDoc-Ordner mit "glob" ab. (Die Erklärung des Prozesses pro Zip-Dekomprimierung wird weggelassen.)

Code1


xbrl_file_expressions = glob.glob('C:\\Users\\xxx\\Desktop\\xbrlReport\\SR\\XBRL\\PublicDoc\\*.xbrl')

Result1


['C:\\Users\\XXX\\Desktop\\xbrlReport\\SR\\XBRL\\PublicDoc\\jpcrp030000-asr-001_E00112-000_2019-03-31_01_2019-06-27.xbrl', 'C:\\Users\\XXX\\Desktop\\xbrlReport\\SR\\XBRL\\PublicDoc\\jpcrp030000-asr-001_E01422-000_2019-03-31_01_2019-06-27.xbrl', 'C:\\Users\\XXX\\Desktop\\xbrlReport\\SR\\XBRL\\PublicDoc\\jpcrp030000-asr-001_E02770-000_2019-03-31_01_2019-06-21.xbrl', 'C:\\Users\\XXX\\Desktop\\xbrlReport\\SR\\XBRL\\PublicDoc\\jpcrp030000-asr-001_E04510-000_2019-03-31_01_2019-06-27.xbrl']

Die Schleifenverarbeitung wird unter Verwendung von "xbrl_files" durchgeführt, und XBRL-Daten werden von Arelles modelManager.load (xbrl_file) für jede Instanzdatei gelesen. Als Ergebnis können Sie das model_xbrl-Objekt von Arelle abrufen, das die XBRL-Dateninformationen enthält.

Code2


 for index, xbrl_file in enumerate(xbrl_files):

    ctrl = Cntlr.Cntlr()
    model_manager= ModelManager.initialize(ctrl)
    model_xbrl= modelManager.load(xbrl_file)

Result2



<arelle.ModelXbrl.Model_xbrl object at 0x0EF6F350>

Als nächstes wird die Schleifenverarbeitung unter Verwendung von "model_xbrl.facts" durchgeführt, wobei alle in der Instanz enthaltenen "Fakten" (tatsächliche Daten wie die numerischen Werte der Elemente) im Listenformat definiert werden und der Elementname jeder "Tatsache" ("Tatsache"). get concept.qname.localName). Wenn der Elementname der diesmal zu extrahierende Elementname ist, ist dies ein Mechanismus zum Erfassen des numerischen Werts (fact.value`) des Elements. Integrieren Sie bei der Verarbeitung von EDINETCODE die Logik zur Identifizierung der Branche des Unternehmens anhand von "EdinetcodeDlInfo.csv". In Bezug auf die Anzahl der Mitarbeiter wird die aktuelle Periode ("CurrentYearInstant") im Periodenattribut "context" angegeben, da derselbe Elementname mehrmals existiert.

Code3


for fact in model_xbrl.facts:
    if fact.concept.qname.localName == 'EDINETCodeDEI':
        edinet_code = fact.value

        for code_name in edinet_info_list:
            if code_name[0] == edinet_code:
                industry_code = code_name[1]
                break

 elif fact.concept.qname.localName=='FilerNameInJapaneseDEI':
 elif fact.concept.qname.localName=='AverageAnnualSalaryInformationAboutReportingCompanyInformationAboutEmployees':
 elif fact.concept.qname.localName=='AverageLengthOfServiceYearsInformationAboutReportingCompanyInformationAboutEmployees':
 elif fact.concept.qname.localName=='AverageLengthOfServiceMonthsInformationAboutReportingCompanyInformationAboutEmployees':
 elif fact.concept.qname.localName=='AverageAgeYearsInformationAboutReportingCompanyInformationAboutEmployees':
 elif fact.concept.qname.localName=='AverageAgeMonthsInformationAboutReportingCompanyInformationAboutEmployees':
 elif fact.concept.qname.localName=='NumberOfEmployees':
     if fact.contextID == 'CurrentYearInstant_NonConsolidatedMember':

Danach werden die Informationen jedes erfassten Elements ("edinet_code", "filer_name_jp", "branch_code", "Salary_info", "service_years", "age_years", "number_of_employees") in "company_info_list" gespeichert. Wenn zu diesem Zeitpunkt die durchschnittlichen Dienstjahre (Monate) (service_months) und das durchschnittliche Alter (Monate) ( age_months) vorhanden sind, haben wir einen Prozess integriert, um sie in Jahre umzuwandeln. Wenn Sie danach company_info_list in der EDINET CODE-Einheit (Instanzdateieinheit) in edinet_company_info_list speichern, wird eine Liste mit Informationen zu Mitarbeitern der einzelnen Unternehmen vervollständigt.

Code4


    company_info_list.append(edinet_code)
    company_info_list.append(filer_name_jp)
    company_info_list.append(industry_code)
    company_info_list.append(salary_info)

    if len(service_months) != 0:
        service_years_decimal= round(int(service_months)/12,1)
        service_years = int(service_years) + service_years_decimal
        service_years = str(service_years)

    company_info_list.append(service_years)

    if len(age_months) != 0:
        age_years_decimal= round(int(age_months)/12,1)
        age_years = int(age_years) + age_years_decimal
        age_years = str(age_years)

    company_info_list.append(age_years)
    company_info_list.append(number_of_employees)

    edinet_company_info_list.append(Company_info_list)

Die edinet_company_info_list sieht folgendermaßen aus:

Result4


[['E00112', 'Totetsu Kogyo Co., Ltd.', 'Bauindustrie', '8547489', '13.8', '41.2', '1673'], ['E01422', 'Fuji Sash Co., Ltd.', 'Metallprodukte', '5527000', '20.7', '44.7', '850'], ['E02770', 'Hauptsitz der Misumi-Gruppe', 'Großhandel', '', '', '', '1293'], ['E04510', 'Power Development Co., Ltd.', 'Strom- und Gasindustrie', '7980312', '19.6', '40.9', '2445']・ ・ ・]

Schließlich wird die erhaltene "edinet_company_info_list" im CSV-Format ausgegeben. Damit ist die Extraktion der erforderlichen Elemente abgeschlossen.

Code5


employee_frame = pd.DataFrame(edinet_company_info_list,
                         columns=['EDINETCODE', 'Name der Firma', 'Industrie', 'Durchschnittliches Jahresgehalt (Yen)', 'Durchschnittliche Dienstjahre (Jahre)', 'Durchschnittsalter (Jahre)', 'Anzahl der Mitarbeiter (Personen)'])
employee_frame.to_csv("C://Users//xxx//Desktop//xbrlReport//xbrl_qiita.csv", encoding='cp932')

Übrigens, wenn Sie das Programm ausführen, wird am Ende die folgende CSV-Datei ausgegeben. Abhängig von der Methode der Offenlegung von Unternehmen gibt es verschiedene Arten von durchschnittlichen jährlichen Gehaltseinheiten (Yen, 1.000 Yen usw.). Obwohl wir Daten ab April 2019 als Ziel haben, gibt es aufgrund des Geschäftsjahresendes jedes Unternehmens einige, die noch nicht markiert wurden, und wir können keine gehaltsbezogenen Daten erhalten.

2. Quellcode


# -*- coding: utf-8 -*-

from arelle import ModelManager
from arelle import Cntlr
import os
import zipfile
import glob
import pandas as pd


def make_edinet_info_list(edinetcodedlinfo_filepath):
    edinet_info = pd.read_csv(edinetcodedlinfo_filepath, skiprows=1,
                                 encoding='cp932')
    edinet_info = edinet_info[["EDINET-Code", "Einreicherindustrie"]]
    edinet_info_list = edinet_info.values.tolist()
    return edinet_info_list

def unzip_file(zip_dir,xbrl_file_expressions):
    zip_files = glob.glob(os.path.join(zip_dir, '*.zip'))

    number_of_zip_lists = len(zip_files)
    print("number_of_zip_lists:", number_of_zip_lists)

    for index, zip_file in enumerate(zip_files):
        print(zip_file, ":", index + 1, "/", number_of_zip_lists)
        with zipfile.ZipFile(zip_file) as zip_f:
            zip_f.extractall(zip_dir)
            zip_f.close()

    xbrl_files = glob.glob(xbrl_file_expressions)
    return xbrl_files

def make_edinet_company_info_list(xbrl_files,edinet_info_list):
    edinet_company_info_list = []
    for index, xbrl_file in enumerate(xbrl_files):
        edinet_code = ""  # EDINETCODE
        filer_name_jp = ""  #Name der Firma
        industry_code = ""  #Industrie
        salary_info = ""  #Durchschnittliches Jahresgehalt (Yen)
        service_years = ""  #Durchschnittliche Dienstjahre (Jahre)
        service_months = ""  #Durchschnittliche Dienstjahre (Monat)
        age_years = ""  #Durchschnittsalter (Jahre)
        age_months = ""  #Durchschnittsalter (Monat)
        number_of_employees = ""  #Anzahl der Mitarbeiter (Personen)
        company_info_list = []  #Unternehmensinformationen

        ctrl = Cntlr.Cntlr()
        model_manager = ModelManager.initialize(ctrl)
        model_xbrl = model_manager.load(xbrl_file)

        print(xbrl_file, ":", index + 1, "/", len(xbrl_files))

        for fact in model_xbrl.facts:

            if fact.concept.qname.localName == 'EDINETCodeDEI':
                print("EDINET-Code", fact.value)
                edinet_code = fact.value

                for code_name in edinet_info_list:
                    if code_name[0] == edinet_code:
                        print("Industrie",code_name[1])
                        industry_code = code_name[1]
                        break

            elif fact.concept.qname.localName == 'FilerNameInJapaneseDEI':
                print("Name der Firma", fact.value)
                filer_name_jp = fact.value

            elif fact.concept.qname.localName == 'AverageAnnualSalaryInformationAboutReportingCompanyInformationAboutEmployees':
                print("Durchschnittliches Jahresgehalt (Yen)", fact.value)
                salary_info = fact.value

            elif fact.concept.qname.localName == 'AverageLengthOfServiceYearsInformationAboutReportingCompanyInformationAboutEmployees':
                print("Durchschnittliche Dienstjahre (Jahre)", fact.value)
                service_years = fact.value

            elif fact.concept.qname.localName == 'AverageLengthOfServiceMonthsInformationAboutReportingCompanyInformationAboutEmployees':
                print("Durchschnittliche Dienstjahre (Monat)", fact.value)
                service_months = fact.value

            elif fact.concept.qname.localName == 'AverageAgeYearsInformationAboutReportingCompanyInformationAboutEmployees':
                print("Durchschnittsalter (Jahre)", fact.value)
                age_years = fact.value

            elif fact.concept.qname.localName == 'AverageAgeMonthsInformationAboutReportingCompanyInformationAboutEmployees':
                print("Durchschnittsalter (Monat)", fact.value)
                age_months = fact.value

            elif fact.concept.qname.localName == 'NumberOfEmployees':
                if fact.contextID == 'CurrentYearInstant_NonConsolidatedMember':
                    print("Anzahl der Mitarbeiter (Personen)", fact.value)
                    number_of_employees = fact.value

        print("")
        company_info_list.append(edinet_code)
        company_info_list.append(filer_name_jp)
        company_info_list.append(industry_code)
        company_info_list.append(salary_info)

        if len(service_months) != 0:
            service_years_decimal = round(int(service_months) / 12, 1)
            service_years = int(service_years) + service_years_decimal
            service_years = str(service_years)

        company_info_list.append(service_years)

        if len(age_months) != 0:
            age_years_decimal = round(int(age_months) / 12, 1)
            age_years = int(age_years) + age_years_decimal
            age_years = str(age_years)

        company_info_list.append(age_years)
        company_info_list.append(number_of_employees)

        edinet_company_info_list.append(company_info_list)

    return edinet_company_info_list

def write_csv_of_employee_info(edinet_company_info_list):

    employee_frame = pd.DataFrame(edinet_company_info_list,
                         columns=['EDINETCODE', 'Name der Firma', 'Industrie', 'Durchschnittliches Jahresgehalt (Yen)', 'Durchschnittliche Dienstjahre (Jahre)', 'Durchschnittsalter (Jahre)', 'Anzahl der Mitarbeiter (Personen)'])

    print(employee_frame)
    employee_frame.to_csv("C://Users//xxx//Desktop//xbrlReport//xbrl_qiita.csv", encoding='cp932')


def main():
    edinetcodedlinfo_filepath = 'C://Users//xxx//Desktop//xbrlReport//EdinetcodeDlInfo.csv'
    edinet_info_list = make_edinet_info_list(edinetcodedlinfo_filepath)

    zip_dir = 'C://Users//xxx//Desktop//xbrlReport//SR//'
    xbrl_file_expressions = 'C://Users//xxx//Desktop//xbrlReport//SR//XBRL//PublicDoc//*.xbrl'
    xbrl_files = unzip_file(zip_dir,xbrl_file_expressions)

    edinet_company_info_list = make_edinet_company_info_list(xbrl_files,edinet_info_list)
    print(edinet_company_info_list)

    write_csv_of_employee_info(edinet_company_info_list)
    print("extract finish")

if __name__ == "__main__":
    main()


3. So extrahieren Sie andere Informationen als Mitarbeiterinformationen

Der in XBRL (ex.EDINETCodeDEI) definierte Elementname wurde ohne besondere Erklärung beschrieben, aber alle diese werden auf der EDINET-Site veröffentlicht. Die neueste Version vom Dezember 2019 ist die "Taxonomie-Elementliste" und "Kontoliste" von Über die Veröffentlichung der EDINET-Taxonomie 2020. Sie können von überprüfen. Die diesmal extrahierten Themen sind in der Taxonomieelementliste (1e_ElementList.xlsx`) aufgeführt. Einzelheiten finden Sie unter [Kabinettsverordnung Nr. 3, Formular Wertpapierbericht über die Offenlegung von Unternehmensdetails usw. (jpcrp030000-asr)] - [9] Blatt --212000b Mitarbeiterstatus (jpcrp_212000-002_2019-11-01_pre.xml) ), Bitte prüfen. Mithilfe dieser Listen können verschiedene andere Themen als Mitarbeiterinformationen extrahiert werden. Die EDINET-Taxonomie kann aktualisiert werden, um auf die Überarbeitung von Gesetzen und Rechnungslegungsstandards zu reagieren. Stellen Sie daher vor der Verarbeitung einer Instanz sicher, dass die EDINET-Taxonomieversion korrekt ist.

4. Kontaktinformationen

Bei Fragen zu diesem Artikel wenden Sie sich bitte an die folgende E-Mail-Adresse. e-mail:[email protected] (Natürlich sind auch Kommentare zu Qiita willkommen)

Diese E-Mail-Adresse ist die Kontaktstelle für Anfragen zum Entwicklungsausschuss von XBRL Japan, der den Artikel über Qiita schreibt. Ich werde. Daher können wir je nach Inhalt keine allgemeinen Anfragen zur Organisation beantworten. Bei technischen Fragen, Meinungen, Anfragen, Ratschlägen usw. zu XBRL können Sie sich jedoch gerne an uns wenden. Bitte beachten Sie, dass die Beantwortung einige Zeit in Anspruch nehmen kann, da die Ausschussmitglieder Freiwillige sind.

Recommended Posts

Lassen Sie uns automatisch Mitarbeiterinformationen wie das Durchschnittsgehalt aus den von EDINET (5/10) veröffentlichten XBRL-Daten extrahieren.
Lassen Sie uns die Beziehung zwischen Durchschnittsgehalt und Industrie mit XBRL-Daten und Seaborn visualisieren! (7/10)
Legen Sie Informationen wie die Länge am Rand von NetworkX fest
Informationsextraktion aus der EDINET XBRL-Datei