Ik heb een dataframe in panda’s dat ik naar een CSV-bestand wil schrijven. Ik doe dit met:
df.to_csv('out.csv')
En krijg de foutmelding:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u03b1' in position 20: ordinal not in range(128)
Is er een manier om dit gemakkelijk te omzeilen (d.w.z. ik heb unicode-tekens in mijn dataframe)? En is er een manier om naar een door tabs gescheiden bestand te schrijven in plaats van een CSV met b.v. een ‘naar-tab’-methode (waarvan ik denk dat die niet bestaat)?
Antwoord 1, autoriteit 100%
Om door een tab te scheiden, kunt u het argument sep
van to_csv
:
df.to_csv(file_name, sep='\t')
Om een specifieke codering (bijv. ‘utf-8’) te gebruiken, gebruikt u het argument encoding
:
df.to_csv(file_name, sep='\t', encoding='utf-8')
Antwoord 2, autoriteit 24%
Wanneer u een DataFrame
-object opslaat in een csv-bestand met behulp van de to_csv
-methode, hoeft u waarschijnlijk de >voorafgaand aan indexen van elke rij van het DataFrame
-object.
Je kunt dit vermijden door een False
booleaanse waarde door te geven aan de index
parameter.
Een beetje zoals:
df.to_csv(file_name, encoding='utf-8', index=False)
Dus als uw DataFrame-object zoiets is als:
Color Number
0 red 22
1 blue 10
Het csv-bestand bevat:
Color,Number
red,22
blue,10
in plaats van (het geval waarin de standaardwaarde True
werd doorgegeven)
,Color,Number
0,red,22
1,blue,10
Antwoord 3, autoriteit 3%
Als je een pandas DataFrame naar een CSV-bestand wilt schrijven, heb je DataFrame.to_csv
. Deze functie biedt veel argumenten met redelijke standaardwaarden die u vaker wel dan niet zult moeten overschrijven om aan uw specifieke gebruiksgeval te voldoen. U wilt bijvoorbeeld een ander scheidingsteken gebruiken, de datum/tijd-notatie wijzigen of de index laten vallen tijdens het schrijven. to_csv
heeft argumenten die u kunt doorgeven om aan deze vereisten te voldoen.
Hier is een tabel met enkele veelvoorkomende scenario’s voor het schrijven naar CSV-bestanden en de bijbehorende argumenten die u daarvoor kunt gebruiken.
Voetnoten
- Het standaard scheidingsteken wordt verondersteld een komma te zijn (
','
). Verander dit niet tenzij je weet dat het nodig is.- Standaard wordt de index van
df
geschreven als de eerste kolom. Als uw DataFrame geen index heeft (IOW, dedf.index
is de standaardRangeIndex
), dan wilt uindex=False
bij het schrijven. Om dit op een andere manier uit te leggen, als uw gegevens WEL een index hebben, kunt u (en moet)index=True
gebruiken of het gewoon helemaal weglaten (de standaardinstelling isTrue
code>).- Het is verstandig om deze parameter in te stellen als u stringgegevens schrijft, zodat andere toepassingen weten hoe ze uw gegevens moeten lezen. Dit voorkomt ook mogelijke
UnicodeEncodeError
s die u kunt tegenkomen tijdens het opslaan.- Compressie wordt aanbevolen als u grote DataFrames (>100K rijen) naar schijf schrijft, omdat dit resulteert in veel kleinere uitvoerbestanden.
OTOH, zal dit betekenen dat de schrijftijd zal toenemen (en bijgevolg zal de
leestijd aangezien het bestand moet worden gedecomprimeerd).
Antwoord 4, autoriteit 2%
Iets anders dat u kunt proberen als u problemen heeft met het coderen naar ‘utf-8’ en cel voor cel wilt gaan, kunt u het volgende proberen.
Python 2
(Waarbij “df” uw DataFrame-object is.)
for column in df.columns:
for idx in df[column].index:
x = df.get_value(idx,column)
try:
x = unicode(x.encode('utf-8','ignore'),errors ='ignore') if type(x) == unicode else unicode(str(x),errors='ignore')
df.set_value(idx,column,x)
except Exception:
print 'encoding error: {0} {1}'.format(idx,column)
df.set_value(idx,column,'')
continue
Probeer dan:
df.to_csv(file_name)
U kunt de codering van de kolommen controleren door:
for column in df.columns:
print '{0} {1}'.format(str(type(df[column][0])),str(column))
Waarschuwing: errors=’ignore’ zal het teken weglaten, bijvoorbeeld
IN: unicode('Regenexx\xae',errors='ignore')
OUT: u'Regenexx'
Python 3
for column in df.columns:
for idx in df[column].index:
x = df.get_value(idx,column)
try:
x = x if type(x) == str else str(x).encode('utf-8','ignore').decode('utf-8','ignore')
df.set_value(idx,column,x)
except Exception:
print('encoding error: {0} {1}'.format(idx,column))
df.set_value(idx,column,'')
continue
Antwoord 5
Voorbeeld van export in bestand met volledig pad in Windows en in het geval dat uw bestand headers heeft:
df.to_csv (r'C:\Users\John\Desktop\export_dataframe.csv', index = None, header=True)
Als u het bestand bijvoorbeeld in dezelfde map wilt opslaan als uw script, met utf-8-codering en tab als scheidingsteken:
df.to_csv(r'./export/dftocsv.csv', sep='\t', encoding='utf-8', header='true')
Antwoord 6
Soms heb je met deze problemen te maken als je ook UTF-8-codering opgeeft.
Ik raad u aan om codering op te geven tijdens het lezen van het bestand en dezelfde codering tijdens het schrijven naar een bestand.
Dit zou je probleem kunnen oplossen.
Antwoord 7
het zou in dit geval niet het antwoord kunnen zijn, maar aangezien ik dezelfde foutmelding kreeg met .to_csv
Ik probeerde .toCSV('name.csv')
en het foutbericht was anders (“SparseDataFrame' object has no attribute 'toCSV'
). Het probleem werd dus opgelost door dataframe om te zetten in dicht dataframe
df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Antwoord 8
Als de avobe-oplossing voor niemand werkt of de CSV in de war raakt, verwijder dan gewoon sep='\t'
uit de regel als volgt:
df.to_csv(file_name, encoding='utf-8')