2017-07-19 4 views
0

Szenario: Ich habe diesen kleinen Frankenstein eines Codes (mit ein paar tollen Hilfe von SO-Benutzern) zusammengestellt, um Daten von Excel-Dateien zu erhalten und in einen Pandas-Datenrahmen zu legen.Lesen von Daten von xlsx in Pandas Datenrahmen

Was ich versuche zu tun: Ich versuche, Daten von Dateien zu erhalten, die ein oder mehrere Arbeitsblätter von Daten enthalten können. Danach beabsichtige ich, den Datenrahmen entsprechend zu organisieren. Zum Beispiel:

date1 identifier 1 bid  ask 
date1 identifier 2 bid  ask 
date1 identifier 3 bid  ask 
date2 identifier 1 bid  ask 
date2 identifier 3 bid  ask 
date3 identifier 4 bid  ask 
date3 identifier 5 bid  ask 

Obs1: Jede Datei kann Wert für "Bid" hat, "Fragen" oder beide jeweils in einem separaten Arbeitsblatt.

Obs2: Die Bezeichner und Daten können in Dateien identisch sein oder auch nicht.

Was ich bis jetzt tat: Mein aktueller Code liest die Dateien und jedes Arbeitsblatt. Wenn es der Bedingung folgt, hängt es an einen bestimmten Datenrahmen an. Dann werden die Spaltenüberschriften korrigiert.

Problem: Wenn mein Code ausgeführt wird, gibt es aus irgendeinem Grund zwei leere Datenframes.

Frage: Wie kann ich verschiedene Arbeitsblätter berücksichtigen und die Werte entsprechend (zu der obigen Struktur) an einen Datenrahmen ausgeben?

Aktuelle Code:

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import glob, os 
import datetime as dt 
from datetime import datetime 
import matplotlib as mpl 
from openpyxl import load_workbook 


directory = os.path.join("C:\\","Users\\DGMS\\Desktop\\final 2")   
list_of_dfs = [] 
dfbid = pd.DataFrame() 
dfask = pd.DataFrame() 

for root,dirs,files in os.walk(directory): 

    for file in files: 

     f = os.path.join(root, file) 

     wb = load_workbook(f) 

     for sheet in wb.worksheets: 
      if sheet == "Bid": 
       dfbid = pd.concat([dfbid, pd.read_excel(f, "Bid")]) 
       for i in range(1,len(dfbid.columns)): 
        dfbid.columns.values[i] = pd.to_datetime(dfbid.columns.values[i]) 

      elif sheet == "Ask": 
       dfask = pd.concat([dfask, pd.read_excel(f, "Ask")]) 
       for i in range(1,len(dfask.columns)): 
        dfask.columns.values[i] = pd.to_datetime(dfask.columns.values[i]) 

Antwort

2

Trennen Sie die verschiedenen Dinge, die Ihr Code in verschiedenen Funktionen der Fall ist.

  • Look für die Excel-Dateien
  • lesen Sie die Excel-Dateien
  • konvertieren den Inhalt datetime
  • verketten die Datenrahmen

diese Weise können Sie separat jeden Schritt überprüfen und kontrollieren können anstatt es alles miteinander verflochten haben

Suchen Sie nach den Excel-Dateien

import pandas as pd 
from pathlib import Path 

root_dir = Path(r"C:\Users\DGMS\Desktop\final 2") 

files = root_dir.glob('**/*.xlsx') 

Lesen Sie die Excel-Dateien

jede Datei lesen und geben die Arbeitsblätter 'Bid' und 'Ask', erzeugen dann 2 Listen von Dataframes

def parse_workbook(file): 
    d = pd.read_excel(file, sheetname=None) 
    return d.get('Bid', None), d.get('Ask', None) 

df_bid_dfs, df_ask_dfs = zip(*(parse_workbook(file) for file in files)) 

konvertieren den Inhalt datetime

def parse_datetime(df): 
    for column_name, column in df.iteritems(): 
     df[column_name] = pd.to_datetime(column) 
    return df 

Verketten Sie die DataFrames

df_bid = pd.concat(parse_datetime(df) for df in df_bid_dfs if df) 
df_ask = pd.concat(parse_datetime(df) for df in df_ask_dfs if df) 

Prüfung parse_datetime und die Verkettung

df1 = pd.DataFrame(['20170718']) 
df2 = pd.DataFrame(['20170719']) 
df_bid_dfs = (df1, df2) 
pd.concat(parse_datetime(df) for df in df_bid_dfs) 
0 
0 2017-07-18 
0 2017-07-19 
+2

Soweit ich weiß, 'concat' mit einem Generator Ausdruck funktioniert. Vielleicht nicht in allen Versionen? –

+0

Ich habe einen Code hinzugefügt, um diesen letzten Schritt zu testen –

+0

Vielen Dank für die Antwort. Eine Frage bezüglich der Verkettungsprozedur: Angenommen, einige meiner Dateien haben einige wiederholte Spalten (Daten) oder wiederholte Zeilen (Bezeichner), ist mein Ziel mit Verketten, jede neue Spalte am Ende (links von allen Spalten) und jeder neuen Zeile hinzuzufügen bis zum Ende (unten). Wenn bereits eine Spalte vorhanden ist, wird nur eine neue Zeile hinzugefügt. Wenn diese Zeile bereits vorhanden ist, wird sie nur zur neuen Spalte hinzugefügt. Kann die Verkettung das automatisch machen? Oder muss ich jeweils eine Achse verketten? – DGMS89

Verwandte Themen