bugfix
This commit is contained in:
@@ -715,117 +715,140 @@ def fuzzy_similarity(str1, str2):
|
||||
# Extrahiert und normalisiert Zahlenwerte aus Strings.
|
||||
# Nutzt globale Helfer: clean_text, re.
|
||||
def extract_numeric_value(raw_value, is_umsatz=False):
|
||||
logger = logging.getLogger(__name__ + ".extract_numeric_value") # Logger für diese Funktion
|
||||
logger = logging.getLogger(__name__ + ".extract_numeric_value")
|
||||
if raw_value is None or pd.isna(raw_value):
|
||||
return "k.A."
|
||||
|
||||
raw_value_str_original = str(raw_value).strip()
|
||||
if not raw_value_str_original or raw_value_str_original.lower() in ['k.a.', 'n/a', '-']:
|
||||
text = str(raw_value).strip()
|
||||
if not text or text.lower() in ['k.a.', 'n/a', '-']:
|
||||
return "k.A."
|
||||
|
||||
# Spezifische Behandlung für "0" gemäß Ihrer Regel: Wenn der Input nur "0" ist,
|
||||
# dann ist es für die *Extraktion* erstmal eine 0, die dann in der
|
||||
# *Konsolidierung* ggf. zu "k.A." wird, wenn keine bessere Quelle da ist.
|
||||
# Für die Plausi-Checks wird String "0" dann als NaN (unbekannt) interpretiert.
|
||||
# Hier lassen wir "0" als numerische 0 durch, wenn es die einzige Zahl ist.
|
||||
# Originaltext für spätere Einheitenprüfung (Groß-/Kleinschreibung egal)
|
||||
original_lower = text.lower()
|
||||
|
||||
try:
|
||||
# Schritt 1: Grundlegende Textbereinigung
|
||||
processed_value = clean_text(raw_value_str_original) # Ihre globale clean_text Funktion
|
||||
if processed_value.lower() in ['k.a.', 'n/a', '-']:
|
||||
# Schritt 1: Klammerinhalte und generelle Präfixe/Suffixe entfernen
|
||||
text = re.sub(r'\(.*?\)', '', text) # Klammern und Inhalt entfernen (z.B. Jahreszahlen)
|
||||
text = re.sub(r'(?i)^\s*(ca\.?|circa|rund|etwa|ueber|unter|mehr als|weniger als|bis zu)\s+', '', text)
|
||||
text = re.sub(r'[€$£¥CHF]', '', text, flags=re.IGNORECASE) # Währungssymbole entfernen
|
||||
text = re.split(r'\s*(-|–|bis)\s*', text, 1)[0].strip() # Nur ersten Teil bei Spannen
|
||||
|
||||
# Wenn nach Basisreinigung leer, dann k.A.
|
||||
if not text.strip():
|
||||
return "k.A."
|
||||
|
||||
num_as_float = None
|
||||
number_already_scaled = False # Flag, ob die Zahl bereits durch eine Einheit skaliert wurde
|
||||
|
||||
# Schritt 2: Versuche, Zahlen mit expliziten Einheiten (Mrd, Mio, Tsd) zu matchen
|
||||
# Regex sucht nach: Zahl (optional mit Dezimal/Tausender) gefolgt von Einheit
|
||||
# Die Zahlengruppe (group 1) wird später separat normalisiert
|
||||
einheit_pattern = re.compile(
|
||||
r"""
|
||||
(?P<number>[\d.,' ]+) # Die Zahl selbst, erlaubt Punkte, Kommas, Apostrophe, Leerzeichen
|
||||
\s* # Optionale Leerzeichen
|
||||
(?P<unit>mrd\.?|milliarden|billion|mio\.?|millionen|mill\.?|tsd\.?|tausend|k\b) # Einheiten (k für Tausend)
|
||||
""",
|
||||
re.VERBOSE | re.IGNORECASE
|
||||
)
|
||||
|
||||
match_einheit = einheit_pattern.search(text)
|
||||
|
||||
if match_einheit:
|
||||
num_str_candidate = match_einheit.group("number").strip()
|
||||
unit_str = match_einheit.group("unit").lower()
|
||||
|
||||
# Bereinige den num_str_candidate (Tausender, Dezimal)
|
||||
num_str_candidate = num_str_candidate.replace("'", "").replace(" ", "")
|
||||
if '.' in num_str_candidate and ',' in num_str_candidate:
|
||||
if num_str_candidate.rfind('.') > num_str_candidate.rfind(','): # US
|
||||
num_str_candidate = num_str_candidate.replace(',', '')
|
||||
else: # EU
|
||||
num_str_candidate = num_str_candidate.replace('.', '').replace(',', '.')
|
||||
elif ',' in num_str_candidate: # Nur Komma
|
||||
if num_str_candidate.count(',') == 1 and re.search(r',\d{1,2}$', num_str_candidate) and not re.search(r',\d{3}',num_str_candidate):
|
||||
num_str_candidate = num_str_candidate.replace(',', '.')
|
||||
else:
|
||||
num_str_candidate = num_str_candidate.replace(',', '')
|
||||
elif '.' in num_str_candidate: # Nur Punkt
|
||||
if num_str_candidate.count('.') == 1 and re.search(r'\.\d{1,2}$', num_str_candidate) and not re.search(r'\.\d{3}',num_str_candidate):
|
||||
pass # Dezimalpunkt
|
||||
else:
|
||||
num_str_candidate = num_str_candidate.replace('.', '')
|
||||
|
||||
if re.fullmatch(r'-?\d+(\.\d+)?', num_str_candidate):
|
||||
try:
|
||||
num_as_float = float(num_str_candidate)
|
||||
number_already_scaled = True # Markieren, dass die Einheit schon verarbeitet wurde
|
||||
|
||||
if is_umsatz: # Ziel ist Mio.
|
||||
if unit_str.startswith("mrd") or unit_str.startswith("billion"):
|
||||
num_as_float *= 1000 # von Mrd-Zahl zu Mio-Zahl
|
||||
elif unit_str.startswith("tsd") or unit_str.startswith("tausend") or unit_str == "k":
|
||||
num_as_float /= 1000 # von Tsd-Zahl zu Mio-Zahl
|
||||
# Wenn "mio" oder "millionen", ist num_as_float bereits der Mio-Wert
|
||||
else: # Mitarbeiter, Ziel ist absolute Zahl
|
||||
if unit_str.startswith("mrd") or unit_str.startswith("billion"): num_as_float *= 1000000000
|
||||
elif unit_str.startswith("mio") or unit_str.startswith("millionen") or unit_str.startswith("mill"): num_as_float *= 1000000
|
||||
elif unit_str.startswith("tsd") or unit_str.startswith("tausend") or unit_str == "k": num_as_float *= 1000
|
||||
except ValueError:
|
||||
num_as_float = None # Konnte Zahl vor Einheit nicht parsen
|
||||
number_already_scaled = False
|
||||
else:
|
||||
num_as_float = None # Zahl vor Einheit war nicht valide
|
||||
number_already_scaled = False
|
||||
|
||||
|
||||
# Schritt 3: Wenn keine explizite Einheit gefunden wurde, versuche den Rest als Zahl zu interpretieren
|
||||
if num_as_float is None:
|
||||
num_extraction_str = text.replace("'", "").replace(" ", "") # Globale Leerzeichenentfernung, da keine Einheiten mehr erwartet werden
|
||||
if '.' in num_extraction_str and ',' in num_extraction_str:
|
||||
if num_extraction_str.rfind('.') > num_extraction_str.rfind(','): num_extraction_str = num_extraction_str.replace(',', '')
|
||||
else: num_extraction_str = num_extraction_str.replace('.', '').replace(',', '.')
|
||||
elif ',' in num_extraction_str:
|
||||
if num_extraction_str.count(',') == 1 and re.search(r',\d{1,2}$', num_extraction_str) and not re.search(r',\d{3}',num_extraction_str):
|
||||
num_extraction_str = num_extraction_str.replace(',', '.')
|
||||
else: num_extraction_str = num_extraction_str.replace(',', '')
|
||||
elif '.' in num_extraction_str:
|
||||
if num_extraction_str.count('.') == 1 and re.search(r'\.\d{1,2}$', num_extraction_str) and not re.search(r'\.\d{3}',num_extraction_str):
|
||||
pass
|
||||
else: num_extraction_str = num_extraction_str.replace('.', '')
|
||||
|
||||
if re.fullmatch(r'-?\d+(\.\d+)?', num_extraction_str):
|
||||
try:
|
||||
num_as_float = float(num_extraction_str)
|
||||
except ValueError:
|
||||
logger.debug(f"Konnte '{num_extraction_str}' (aus '{raw_value_str_original}') nicht zu float konvertieren (Fall ohne explizite Einheit).")
|
||||
return "k.A."
|
||||
else:
|
||||
logger.debug(f"Kein valider numerischer String nach Bereinigung (Fall ohne explizite Einheit): '{num_extraction_str}' (Original: '{raw_value_str_original}')")
|
||||
return "k.A."
|
||||
|
||||
# Schritt 2: Präfixe, Suffixe, Währungssymbole und Spannen entfernen
|
||||
processed_value = re.sub(r'(?i)^\s*(ca\.?|circa|rund|etwa|ueber|unter|mehr als|weniger als|bis zu)\s+', '', processed_value)
|
||||
processed_value = re.sub(r'[€$£¥ CHF]', '', processed_value, flags=re.IGNORECASE).strip() # CHF hinzugefügt
|
||||
processed_value = re.split(r'\s*(-|–|bis)\s*', processed_value, 1)[0].strip()
|
||||
|
||||
# Schritt 3: Klammerinhalte entfernen (z.B. Jahreszahlen)
|
||||
num_extraction_str = re.sub(r'\(.*?\)', '', processed_value).strip()
|
||||
|
||||
# Schritt 4: Apostrophe und Leerzeichen zwischen Ziffern entfernen
|
||||
num_extraction_str = num_extraction_str.replace("'", "")
|
||||
num_extraction_str = re.sub(r'(?<=\d)\s+(?=\d)', '', num_extraction_str) # Entfernt Leerzeichen nur zwischen Ziffern
|
||||
# Schritt 4: Finale Skalierung, falls Umsatz und noch nicht durch Einheit geschehen
|
||||
# und die Annahme gilt, dass die Zahl im Sheet bereits Mio. ist.
|
||||
# Diese Funktion soll für die Wiki-Spalten aber den Wert so liefern, wie er für die Spalte passt.
|
||||
# Für Wiki-Umsatz (Spalte S) ist das Mio. €.
|
||||
# Wenn `is_umsatz` True ist und `number_already_scaled` False ist,
|
||||
# bedeutet das, es wurde eine reine Zahl ohne Einheit gefunden (z.B. "173" oder "4380").
|
||||
# Gemäß der Regel "Zahlen in Umsatzspalten sind Mio. €" ist num_as_float dann bereits der Mio-Wert.
|
||||
|
||||
# Keine weitere Skalierung hier nötig, da die Einheitenerkennung oben das bereits erledigt hat
|
||||
# oder bei Umsatz ohne explizite Einheit angenommen wird, dass es Mio. sind.
|
||||
|
||||
if not num_extraction_str: return "k.A."
|
||||
|
||||
# Schritt 5: Punkte und Kommas als Tausender-/Dezimaltrennzeichen standardisieren
|
||||
has_dot = '.' in num_extraction_str
|
||||
has_comma = ',' in num_extraction_str
|
||||
|
||||
if has_dot and has_comma:
|
||||
if num_extraction_str.rfind('.') > num_extraction_str.rfind(','): # US-Stil: 1,234.56
|
||||
num_extraction_str = num_extraction_str.replace(',', '')
|
||||
else: # EU-Stil: 1.234,56
|
||||
num_extraction_str = num_extraction_str.replace('.', '').replace(',', '.')
|
||||
elif has_comma: # Nur Kommas
|
||||
# Wenn es klar wie ein Dezimalkomma aussieht (z.B. ",dd" am Ende, nur ein Komma)
|
||||
# und nicht wie ein Tausender-Komma (z.B. "8,300" -> soll 8300 werden)
|
||||
if num_extraction_str.count(',') == 1 and re.search(r',\d{1,2}$', num_extraction_str) and not re.search(r',\d{3}(,|\s|\Z)', num_extraction_str):
|
||||
num_extraction_str = num_extraction_str.replace(',', '.')
|
||||
else: # Ansonsten sind Kommas Tausendertrenner (z.B. "8,300" -> "8300")
|
||||
num_extraction_str = num_extraction_str.replace(',', '')
|
||||
elif has_dot: # Nur Punkte
|
||||
# Wenn es klar wie ein Dezimalpunkt aussieht (z.B. ".dd" am Ende, nur ein Punkt)
|
||||
if num_extraction_str.count('.') == 1 and re.search(r'\.\d{1,2}$', num_extraction_str) and not re.search(r'\.\d{3}(?!\d)', num_extraction_str):
|
||||
pass # Punkt ist Dezimal, bleibt
|
||||
else: # Ansonsten sind Punkte Tausendertrenner (z.B. "4.380" -> "4380")
|
||||
num_extraction_str = num_extraction_str.replace('.', '')
|
||||
|
||||
# Schritt 6: Finale Validierung und Konvertierung zu float
|
||||
if not re.fullmatch(r'-?\d+(\.\d+)?', num_extraction_str):
|
||||
logger.debug(f"Kein gültiger numerischer String nach Trennzeichenbehandlung: '{num_extraction_str}' (Original: '{raw_value_str_original}')")
|
||||
return "k.A."
|
||||
|
||||
num_as_float = float(num_extraction_str)
|
||||
|
||||
# Schritt 7: Einheiten-Skalierung
|
||||
scaled_num = num_as_float
|
||||
original_lower = raw_value_str_original.lower() # Verwende den ursprünglichen String für Keyword-Suche
|
||||
|
||||
# Für Wiki-Umsatz: Ziel ist Wert in Millionen
|
||||
if is_umsatz:
|
||||
if re.search(r'\bmrd\s*\b|\bmilliarden\s*\b|\bbillion\s*\b', original_lower):
|
||||
scaled_num = num_as_float * 1000.0 # z.B. "1,636 Mrd" -> num_as_float=1.636 -> 1636 (Mio)
|
||||
elif re.search(r'\btsd\s*\b|\btausend\s*\b', original_lower):
|
||||
scaled_num = num_as_float / 1000.0 # z.B. "500 Tsd" -> num_as_float=500 -> 0.5 (Mio)
|
||||
# Wenn keine Einheit wie Mrd/Tsd explizit da ist, wird angenommen, dass num_as_float
|
||||
# bereits den Wert in der im Sheet gewünschten Einheit (Mio für Umsatz) darstellt,
|
||||
# *falls die Zahl aus einer Quelle stammt, die bereits in Mio ist (wie CRM)*.
|
||||
# Bei Wikipedia ist das nicht immer der Fall. Wenn "Mio" explizit da steht, ist es gut.
|
||||
# Wenn nur eine Zahl da steht (z.B. "4380" nach Bereinigung von "4.380"),
|
||||
# müssen wir entscheiden, ob das schon Mio sind oder die Grundeinheit.
|
||||
# Da die Spalte S "Wiki Umsatz" als "normalisiert in Mio. €" definiert ist,
|
||||
# sollte diese Funktion einen Wert zurückgeben, der Mio. € darstellt.
|
||||
# Wenn also die Infobox "4,869 billion" (Barilla) hat, wird `num_as_float` zu 4.869.
|
||||
# Der `re.search` für Mrd/billion wird das erkennen und `scaled_num` zu `4869.0` (Mio) machen.
|
||||
# Wenn die Infobox "1.636 Mrd" hat, wird `num_as_float` zu 1.636, `scaled_num` zu 1636 (Mio).
|
||||
# Wenn die Infobox nur "4380" hätte (ohne Mio/Mrd), würde `num_as_float` 4380 sein und `scaled_num` 4380 (Mio).
|
||||
# Das scheint die korrekte Interpretation für die Wiki-Spalte zu sein.
|
||||
|
||||
else: # Mitarbeiter (absolute Zahl)
|
||||
if re.search(r'\bmrd\s*\b|\bmilliarden\s*\b|\bbillion\s*\b', original_lower):
|
||||
scaled_num = num_as_float * 1000000000.0
|
||||
elif re.search(r'\bmio\s*\b|\bmillionen\s*\b|\bmill[.]?\s*\b', original_lower):
|
||||
scaled_num = num_as_float * 1000000.0
|
||||
elif re.search(r'\btsd\s*\b|\btausend\s*\b', original_lower):
|
||||
scaled_num = num_as_float * 1000.0
|
||||
|
||||
# Runde auf Ganzzahl für die Ausgabe im Sheet, aber nur wenn > 0
|
||||
if scaled_num > 0:
|
||||
return str(int(round(scaled_num)))
|
||||
elif scaled_num == 0: # Wenn das Ergebnis exakt 0 ist (z.B. aus "0 Tsd")
|
||||
# Schritt 5: Rückgabeformat
|
||||
if num_as_float is not None:
|
||||
if num_as_float == 0 and raw_value_str_original.strip() in ['0', '0.0', '0,00', '0.000', '0.00']:
|
||||
return "0" # Explizite "0" im Input wird als String "0" zurückgegeben
|
||||
elif num_as_float > 0:
|
||||
return str(int(round(num_as_float)))
|
||||
elif num_as_float == 0: # Ergebnis einer Berechnung, z.B. "0 Tsd"
|
||||
return "0"
|
||||
else: # Negativ oder Fehler
|
||||
return "k.A."
|
||||
else: # Negativ
|
||||
return "k.A." # Oder wie negative Zahlen behandelt werden sollen
|
||||
else:
|
||||
return "k.A."
|
||||
|
||||
except ValueError as e: # Fehler bei float()
|
||||
logger.debug(f"extract_numeric_value: ValueError '{e}' bei Konvertierung von '{num_extraction_str if 'num_extraction_str' in locals() and isinstance(num_extraction_str, str) else raw_value_str_original[:30]}...'")
|
||||
return "k.A."
|
||||
except Exception as e_general:
|
||||
logger.error(f"Unerwarteter Fehler in extract_numeric_value für '{raw_value_str_original[:50]}...': {e_general}")
|
||||
logger.debug(traceback.format_exc())
|
||||
return "k.A."
|
||||
# Fallback, sollte nicht erreicht werden
|
||||
return "k.A."
|
||||
|
||||
|
||||
# --- Numerische Extraktion fuer FILTERLOGIK (gibt 0 statt k.A. zurueck) ---
|
||||
@@ -7960,86 +7983,39 @@ class DataProcessor:
|
||||
# Innerhalb der DataProcessor Klasse (ersetzen Sie Ihre bestehende Version vollständig hiermit)
|
||||
def _get_numeric_value_for_plausi(self, value_str, is_umsatz=False):
|
||||
logger = logging.getLogger(__name__ + "._get_numeric_value_for_plausi")
|
||||
if value_str is None or pd.isna(value_str): return np.nan
|
||||
raw_value_str_clean = str(value_str).strip()
|
||||
|
||||
# Schritt 1: Nutze die globale, verbesserte extract_numeric_value,
|
||||
# um einen sauberen Zahlenstring oder "k.A."/"0" zu bekommen.
|
||||
# extract_numeric_value liefert Umsatz bereits in Mio, MA absolut.
|
||||
extracted_val_str = extract_numeric_value(value_str, is_umsatz)
|
||||
|
||||
# Explizit "0" und andere "unbekannt" Strings als NaN behandeln
|
||||
if raw_value_str_clean.lower() in ['', 'k.a.', 'n/a', '-', '0', '0.0', '0,00', '0.000', '0.00']:
|
||||
logger.debug(f"Input '{raw_value_str_clean}' als 'unbekannt' (NaN) interpretiert.")
|
||||
if extracted_val_str.lower() in ['k.a.']:
|
||||
logger.debug(f"Input '{value_str}' -> extrahiert zu '{extracted_val_str}' -> NaN (als 'unbekannt' interpretiert).")
|
||||
return np.nan
|
||||
|
||||
# Schritt 1: Grundlegende Textbereinigung
|
||||
temp_val = clean_text(raw_value_str_clean)
|
||||
if temp_val.lower() in ['k.a.', 'n/a', '-']: return np.nan # Erneute Prüfung nach clean_text
|
||||
|
||||
# Schritt 2: Präfixe, Suffixe, Währungssymbole und Spannen entfernen
|
||||
temp_val = re.sub(r'(?i)^\s*(ca\.?|circa|rund|etwa|ueber|unter|mehr als|weniger als|bis zu)\s+', '', temp_val)
|
||||
temp_val = re.sub(r'[€$£¥]', '', temp_val).strip()
|
||||
temp_val = re.split(r'\s*(-|–|bis)\s*', temp_val, 1)[0].strip()
|
||||
|
||||
# Schritt 3: Klammerinhalte entfernen
|
||||
num_extraction_str = re.sub(r'\(.*?\)', '', temp_val).strip()
|
||||
|
||||
# Schritt 4: Apostrophe und Leerzeichen zwischen Ziffern entfernen
|
||||
num_extraction_str = num_extraction_str.replace("'", "")
|
||||
num_extraction_str = re.sub(r'(?<=\d)\s+(?=\d)', '', num_extraction_str)
|
||||
|
||||
if not num_extraction_str: return np.nan
|
||||
|
||||
# Schritt 5: Punkte und Kommas als Tausender-/Dezimaltrennzeichen standardisieren
|
||||
has_dot = '.' in num_extraction_str
|
||||
has_comma = ',' in num_extraction_str
|
||||
|
||||
if has_dot and has_comma:
|
||||
if num_extraction_str.rfind('.') > num_extraction_str.rfind(','):
|
||||
num_extraction_str = num_extraction_str.replace(',', '')
|
||||
else:
|
||||
num_extraction_str = num_extraction_str.replace('.', '').replace(',', '.')
|
||||
elif has_comma:
|
||||
if num_extraction_str.count(',') == 1 and re.search(r',\d{1,2}$', num_extraction_str) and not re.search(r',\d{3}', num_extraction_str):
|
||||
num_extraction_str = num_extraction_str.replace(',', '.')
|
||||
else:
|
||||
num_extraction_str = num_extraction_str.replace(',', '')
|
||||
elif has_dot:
|
||||
if num_extraction_str.count('.') == 1 and re.search(r'\.\d{1,2}$', num_extraction_str) and not re.search(r'\.\d{3}', num_extraction_str):
|
||||
pass
|
||||
else:
|
||||
num_extraction_str = num_extraction_str.replace('.', '')
|
||||
|
||||
# Schritt 6: Finale Validierung und Konvertierung zu float
|
||||
if not re.fullmatch(r'-?\d+(\.\d+)?', num_extraction_str):
|
||||
logger.debug(f"Kein gültiger numerischer String nach Trennzeichenbehandlung: '{num_extraction_str}' (Original: '{raw_value_str_clean}')")
|
||||
return np.nan
|
||||
|
||||
# Wenn extract_numeric_value "0" zurückgibt, bedeutet das nach Ihrer Regel "unbekannt".
|
||||
if extracted_val_str == "0":
|
||||
logger.debug(f"Input '{value_str}' -> extrahiert zu '{extracted_val_str}' -> NaN (als 'unbekannt' interpretiert).")
|
||||
return np.nan
|
||||
|
||||
try:
|
||||
num_val = float(num_extraction_str) # Der reine Zahlenwert aus dem String
|
||||
# extracted_val_str sollte jetzt eine saubere Zahl als String sein (z.B. "173", "4380")
|
||||
# oder es wurde schon "k.A." zurückgegeben.
|
||||
num_val_sheet_unit = float(extracted_val_str) # z.B. 173.0 (Mio) für Umsatz "173"
|
||||
|
||||
# Schritt 7: Einheiten-Skalierung zum absoluten Wert
|
||||
original_lower = raw_value_str_clean.lower()
|
||||
final_num_absolute = num_val
|
||||
final_num_absolute = num_val_sheet_unit
|
||||
if is_umsatz:
|
||||
# num_val_sheet_unit ist bereits in Mio, konvertiere zu absolutem Euro für Plausi-Schwellenwerte
|
||||
final_num_absolute = num_val_sheet_unit * 1000000.0
|
||||
# Für Mitarbeiter ist num_val_sheet_unit bereits die absolute Zahl
|
||||
|
||||
if is_umsatz: # Ziel ist der absolute Euro-Betrag
|
||||
if re.search(r'\bmrd\s*\b|\bmilliarden\s*\b|\bbillion\s*\b', original_lower):
|
||||
final_num_absolute = num_val * 1000000000.0
|
||||
elif re.search(r'\btsd\s*\b|\btausend\s*\b', original_lower):
|
||||
final_num_absolute = num_val * 1000.0
|
||||
else: # Annahme: num_val ist bereits in Mio (z.B. "173" aus CRM), konvertiere zu absolutem Euro
|
||||
final_num_absolute = num_val * 1000000.0
|
||||
else: # Mitarbeiter (absolute Zahl, außer bei expliziten Einheiten)
|
||||
if re.search(r'\bmrd\s*\b|\bmilliarden\s*\b|\bbillion\s*\b', original_lower): final_num_absolute = num_val * 1000000000.0
|
||||
elif re.search(r'\bmio\s*\b|\bmillionen\s*\b|\bmill[.]?\s*\b', original_lower): final_num_absolute = num_val * 1000000.0
|
||||
elif re.search(r'\btsd\s*\b|\btausend\s*\b', original_lower): final_num_absolute = num_val * 1000.0
|
||||
|
||||
# Explizite "0"-Strings wurden oben bereits zu NaN.
|
||||
# Wenn final_num_absolute hier 0.0 ist, dann kam es von einer Berechnung (z.B. "0 Tsd" oder "0 Mio").
|
||||
return final_num_absolute
|
||||
|
||||
except ValueError as e:
|
||||
logger.debug(f"ValueError '{e}' bei Konvertierung von '{num_extraction_str}' (von '{raw_value_str_clean}') -> NaN.")
|
||||
except ValueError:
|
||||
logger.debug(f"ValueError bei Konvertierung von '{extracted_val_str}' (aus Input '{value_str}') zu float in _get_numeric_value_for_plausi.")
|
||||
return np.nan
|
||||
except Exception as e_general:
|
||||
logger.error(f"Unerwarteter Fehler in _get_numeric_value_for_plausi für '{raw_value_str_clean[:50]}...': {e_general}")
|
||||
logger.debug(traceback.format_exc())
|
||||
logger.error(f"Unerwarteter Fehler in _get_numeric_value_for_plausi für '{value_str[:50]}...': {e_general}")
|
||||
return np.nan
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user