• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

NameError: name 'df' is not defined wewnątrz instrukcji warunkowej if

Object Storage Arubacloud
0 głosów
191 wizyt
pytanie zadane 25 sierpnia 2023 w Python przez benek111 Początkujący (260 p.)
edycja 25 sierpnia 2023 przez benek111

Fragment kodu:

        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)
        
#        df

    if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]
        df = df[df[7].str.contains("ES") == False]
        df.drop_duplicates(subset=[0,3,4,7], inplace=True)       
        df
        
    if zakl == 'sluz':
        df = df[df[7].str.contains("WE") == False]
        df = df[df[7].str.contains("WY") == False]   

Ramka jest zaczytywana prawidłowo z pliku. df wyświetla ją prawidłowo.

Po sprawdzeniu warunków if i próbie wykonania instrukcji filtrowania wierszy dostajemy komunikat: 

name 'df' is not defined

Bez instrukcji warunkowej if filtrowanie wierszy przebiega prawidłowo. Czytałem o problemie przy definiowaniu funkcji i definiowaniu wewnątrz tej funkcju df. Ale to nie ten przypadek, zmienna Globalna nie załatwia sprawy. 

komentarz 25 sierpnia 2023 przez adrian17 Ekspert (344,860 p.)
Wrzuć oryginalny kod bez zmian.
komentarz 25 sierpnia 2023 przez benek111 Początkujący (260 p.)
import os
import re
import pandas as pd
from datascroller import scroll
import pyodbc
import keyboard

os.system("mode con cols=210 lines=49")
print('\n Wybierz :\n')
print('0 - Z0  ')
print('1 - Z3  ')
print('2 - Z6  ')
print('3 - Z12 ')
print('4 - Z33 ')
print('5 - Z34 ')
print('6 - Z35 ')
print('9 - We/Wy ')
print('\n\n\n\n, - pasek podświetlajacy')
print('q - wyjście z programu')

while True:
    if keyboard.read_key() == "0":
        zakl = 'Z0'
        break
    if keyboard.read_key() == "1":
        zakl = 'Z3'
        break
    if keyboard.read_key() == "2":
        zakl = 'Z6'
        break
    if keyboard.read_key() == "3":
        zakl = 'Z12'
        break
    if keyboard.read_key() == "4":
        zakl = 'Z33'
        break
    if keyboard.read_key() == "5":
        zakl = 'Z34'
        break 
    if keyboard.read_key() == "6":
        zakl = 'Z35'
        break        
    if keyboard.read_key() == "9":
        zakl = 'sluz'
        break        

path = 'c:\dane'
os.chdir(path)
#print(os.getcwd())
df1 = pd.read_csv('Workers.txt', sep=';', dtype=object, encoding='ANSI')
#df1
#df1.to_csv("wynik2.txt", sep=';', encoding='ANSI', header=None, index=None)
prefix = "prefix"

# iteracja przez listę plików i odczytanie zawartości tych, których nazwy zaczynają się od prefix
for filename in os.listdir(path):
    if os.path.isfile(os.path.basename(filename)) and filename.startswith(prefix):
        print(filename)
        print(os.getcwd())		
       
        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)        
#        df

    if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]
        df = df[df[7].str.contains("ES") == False]
        df.drop_duplicates(subset=[0,3,4,7], inplace=True)        
        df
    df    
    if zakl == 'sluz':
        df = df[df[7].str.contains("WE") == False]
        df = df[df[7].str.contains("WY") == False]   
        df

 

1 odpowiedź

+1 głos
odpowiedź 25 sierpnia 2023 przez adrian17 Ekspert (344,860 p.)
    if os.path.isfile(os.path.basename(filename)) and filename.startswith(prefix):
        print(filename)
        print(os.getcwd())      
        
        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)        
#        df
 
    if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]

Jeśli ten pierwszy `if` nie jest spełniony, to `df` nigdy nie jest ustawiony; późniejszy kod wykonuje się niezależnie czy `df` jest ustawiony czy nie, to pewnie dlatego się wywala. Nie powinieneś po prostu tego wszystkiego wykonywać w środku tego pierwszego `if`a?

Boczne uwagi:

Nie wiem o co chodzi z tymi liniami z samym `df`, to nic nie robi;

for filename in os.listdir(path):
    if os.path.isfile(os.path.basename(filename))

To też jest dziwne; pierwsza linia daje ścieżkę bezwzględną, druga daje ścieżkę względną i polega na wcześniejszym chdir.

dtype=object,

Ustawiając _wszystkie_ kolumny na typ object, mocno wyrzucasz na śmietnik zalety wydajnościowe i pamięciowe pandasa; to powinno dotyczyć tylko kolumn stringowych, nie?

subset=[0,3,4,7],

Ustaw w read_csv listę nazw kolumn, żeby nie trzeba było się indeksami bawić.

komentarz 26 sierpnia 2023 przez benek111 Początkujący (260 p.)
edycja 26 sierpnia 2023 przez benek111

Ten pierwszy 'if' jest spełniony. Masz tam pod spodem #df ( jako marker). To df odczytuje ramkę, więc tu jest w porządku. Wystarczy zrobić # przed

#if zakl != 'sluz':

lub 

#if zakl == 'sluz':

i filtrowanie wykonuje się, df jest "widoczne"

Dodanie warunku 'if' powoduje błąd."name is...."

'If' wykonuje się, wystarczy dać w środku np.

print('Hello')

i się wyświetli. 

 

   Jeśli chodzi o ścieżki, to pliki z danymi były w innych miejscach i trzeba było podawać raz takie raz inne ścieżki. ( to się posprząta).

    dtype=object, tak musi być . To co widzisz to mały wycinek programu. potem są wykonywane różne operacje na na kolumnach tabel i muszą mieć one ten sam typ.

   Jeśli chodzi o nazwy kolumn to nadaje je w dalszej części programu. Osobiście wolę operować na numerkach, tak samo np. wolę podawać IP a nie nazwę sieciową.  To pewnie kwestia gustu  smiley

Zachciało mi się Pythona i teraz zmieniając jedna linijkę kodu w 100 następnych muszę zmieniać wcięcia crying

Ale żeby 'if'' powodowało taki problem z ramką Pandas ?

komentarz 26 sierpnia 2023 przez adrian17 Ekspert (344,860 p.)

Ten pierwszy 'if' jest spełniony.

Wystarczy zrobić # przed `#if zakl != 'sluz':`

no... to właśnie udowodniłeś że błąd dzieje się wtedy, gdy pierwszy `if` nie jest spełniony.

    if os.path.isfile(os.path.basename(filename)) and filename.startswith(prefix):
        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)        
    if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]

To jest obecny kod, ostatnia linijka wykona się nawet jeśli pierwszy `if` się nie spełni, wtedy `df` nie jest przypisane. 

A Twój kod z #:

    if os.path.isfile(os.path.basename(filename)) and filename.startswith(prefix):
        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)        
    #if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]

Teraz ostatnia linia jest częścią pierwszego warunku, więc wykona się tylko jeśli `df` jest przypisane.

Więc tak jak mówiłem, na moje oko masz źle bloki; pewnie powinno być

    if os.path.isfile(os.path.basename(filename)) and filename.startswith(prefix):
        df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)        
        if zakl != 'sluz':
            df = df[df[7].str.contains("YS") == False]

Masz tam pod spodem #df ( jako marker).

Nie wiem co to znaczy "marker". Podtrzymuję że te linie z samym `df` nic nie robią.

dtype=object, tak musi być . To co widzisz to mały wycinek programu. potem są wykonywane różne operacje na na kolumnach tabel i muszą mieć one ten sam typ.

...podtrzymuję że na intuicję, najprawdopodobniej robisz coś źle. Jeśli inna część programu w jakiś sposób to "wymusza", to to ona jest zła. Zazwyczaj kolumna z np mieszanką stringów i liczb jest traktowana jako oczywisty błąd, a nie celowy design.

Jeśli chodzi o nazwy kolumn to nadaje je w dalszej części programu.

Nadal sugeruję żeby były nazwy kolumn od razu, a najlepiej po prostu w nagłówku CSV. Nie bez powodu to jest domyślne zachowanie Pandasa w `read_csv("plik.csv")`.

komentarz 26 sierpnia 2023 przez benek111 Początkujący (260 p.)

Tak. Robię sobie w programie Markery czyli znaczniki miejsc, w których sprawdzam czy jest ok.

Te 'df' wyświetlają ramkę są równoznaczne z print(df).

W tym miejscu, jak pisałem df jest przypisane:

df = pd.read_csv(filename, sep=';', dtype=object, encoding='ANSI', header=None)
df

Wyświetla je właśnie 'df'', więc pierwszy ,if, na pewno się wykonuje.

problem zaczyna się tutaj:

if zakl != 'sluz':
        df = df[df[7].str.contains("YS") == False]

name 'df'' is not defined.

Reszta to są didaskalia. Najpierw musi działać, potem będzie optymalizacja.

 

komentarz 26 sierpnia 2023 przez adrian17 Ekspert (344,860 p.)

Tak. Robię sobie w programie Markery czyli znaczniki miejsc, w których sprawdzam czy jest ok.

Pierwsze słyszę i nie mogę tego zupełnie wyguglować :/ Podlinkujesz o czym mówisz? Chyba że mówisz o breakpointach debuggera...?

W każdym razie... no, mówię co widzę w kodzie. Kod tak jak jest teraz napisany, dopuszcza taką możliwość takiej błędnej ścieżki. Innych na oko nie widzę, pewnie najlepiej żebyś tam debuggerem wpadł albo np wypisywał globals()/locals() etc.

Podobne pytania

0 głosów
2 odpowiedzi 185 wizyt
pytanie zadane 2 stycznia 2017 w Python przez Helmik Użytkownik (680 p.)
0 głosów
2 odpowiedzi 203 wizyt
pytanie zadane 22 października 2019 w C i C++ przez xZenit Użytkownik (760 p.)
0 głosów
1 odpowiedź 163 wizyt
pytanie zadane 6 kwietnia 2022 w JavaScript przez chrystian Gaduła (4,780 p.)

92,579 zapytań

141,432 odpowiedzi

319,657 komentarzy

61,963 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...