web-dev-qa-db-de.com

Neue Zeile aus der CSV-Datei entfernen

Ich möchte das neue Zeilenzeichen in den Daten des CSV-Dateifelds entfernen. Die gleiche Frage wird von mehreren Personen in SO/anderen Orten gestellt. Die angebotenen Lösungen sind jedoch in Skripting. Ich suche nach einer Lösung in Programmiersprachen wie PYTHON oder Spark (nicht nur diese beiden), da ich ziemlich große Dateien habe.

Bisher gestellte Fragen zum gleichen Thema:

Ich habe eine CSV-Datei mit einer Größe von ~ 1 GB und möchte die neuen Zeilenzeichen in den Felddaten entfernen. Das Schema der CSV-Datei variiert dynamisch, daher kann ich das Schema nicht hart codieren. Der Zeilenumbruch erscheint nicht immer vor einem Komma, er erscheint sogar zufällig innerhalb eines Feldes.

Beispieldaten:

playerID,yearID,gameNum,gameName,teamName,lgID,GP,startingPos
gomezle01,1933,1,Cricket,Team1,NYA,AL,1
ferreri01,1933,2,Hockey,"This is 
Team2",BOS,AL,1
gehrilo01,1933,3,"Game name is 
Cricket" 
,Team3,NYA,AL,1
gehrich01,1933,4,Hockey,"Here it is 
Team4",DET,AL,1
dykesji01,1933,5,"Game name is 
Hockey"
,"Team name 
Team5",CHA,AL,1

Erwartete Ausgabe:

playerID,yearID,gameNum,gameName,teamName,lgID,GP,startingPos
gomezle01,1933,1,Cricket,Team1,NYA,AL,1
ferreri01,1933,2,Hockey,"This is Team2",BOS,AL,1
gehrilo01,1933,3,"Game name is Cricket" ,Team3,NYA,AL,1
gehrich01,1933,4,Hockey,"Here it is Team4",DET,AL,1
dykesji01,1933,5,"Game name is Hockey","Team name Team5",CHA,AL,1

Ein Zeilenvorschubzeichen kann in den Daten eines beliebigen Feldes enthalten sein.

Bearbeiten: Screenshot gemäß dem Code:

 enter image description here

4
user805

Wenn Sie pyspark verwenden, würde ich vorschlagen, dass Sie mit der wholeTextFilesname__-Funktion von sparkContext die Datei lesen, da Ihre Datei als vollständiger Text für die entsprechende Analyse gelesen werden muss.

Nach dem Lesen mit wholeTextFilessollten Sie die Zeilenendezeichen durch ersetzen und einige zusätzliche Formatierungen vornehmen, sodass der gesamte Text in Gruppen von acht Zeichenfolgen unterteilt werden kann. 

import re
rdd = sc.wholeTextFiles("path to your csv file")\
    .map(lambda x: re.sub(r'(?!(([^"]*"){2})*[^"]*$),', ' ', x[1].replace("\r\n", ",").replace(",,", ",")).split(","))\
    .flatMap(lambda x: [x[k:k+8] for k in range(0, len(x), 8)])

Sie sollten als Ausgabe ausgegeben werden 

[u'playerID', u'yearID', u'gameNum', u'gameName', u'teamName', u'lgID', u'GP', u'startingPos']
[u'gomezle01', u'1933', u'1', u'Cricket', u'Team1', u'NYA', u'AL', u'1']
[u'ferreri01', u'1933', u'2', u'Hockey', u'"This is Team2"', u'BOS', u'AL', u'1']
[u'gehrilo01', u'1933', u'3', u'"Game name is Cricket"', u'Team3', u'NYA', u'AL', u'1']
[u'gehrich01', u'1933', u'4', u'Hockey', u'"Here it is Team4"', u'DET', u'AL', u'1']
[u'dykesji01', u'1933', u'5', u'"Game name is Hockey"', u'"Team name Team5"', u'CHA', u'AL', u'1']

Wenn Sie alle Array-Rdd-Zeilen in Zeilen von Zeilen konvertieren möchten, können Sie hinzufügen

.map(lambda x: ", ".join(x))

und du solltest bekommen 

playerID, yearID, gameNum, gameName, teamName, lgID, GP, startingPos
gomezle01, 1933, 1, Cricket, Team1, NYA, AL, 1
ferreri01, 1933, 2, Hockey, "This is Team2", BOS, AL, 1
gehrilo01, 1933, 3, "Game name is Cricket", Team3, NYA, AL, 1
gehrich01, 1933, 4, Hockey, "Here it is Team4", DET, AL, 1
dykesji01, 1933, 5, "Game name is Hockey", "Team name Team5", CHA, AL, 1
2
Ramesh Maharjan

Sie können re-, pandas- und io-Module wie folgt verwenden:

import re
import io
import pandas as pd

with open('data.csv','r') as f:
    data = f.read()
df = pd.read_csv(io.StringIO(re.sub('"\s*\n','"',data)))

for col in df.columns: #To replace all line breaks in all textual columns
    if df[col].dtype == np.object_:
        df[col] = df[col].str.replace('\n','');

In [78]: df
Out[78]:
    playerID    yearID  gameNum gameName               teamName        lgID GP  startingPos
0   gomezle01   1933    1       Cricket                Team1           NYA  AL  1
1   ferreri01   1933    2       Hockey                 This is Team2   BOS  AL  1
2   gehrilo01   1933    3       Game name is Cricket   Team3           NYA  AL  1
3   gehrich01   1933    4       Hockey  Here it is     Team4           DET  AL  1
4   dykesji01   1933    5       Game name is Hockey    Team name Team5 CHA  AL  1

Wenn Sie diese DataFrame als Ausgabedatei CSV verwenden möchten, verwenden Sie:

df.to_csv('./output.csv')
1
O.Suleiman

Die Grundidee dieser Lösung besteht darin, Chunks mit fester Länge (Länge gleich der Anzahl der Spalten in der ersten Zeile) mit dem grouper-Rezept zu erhalten. Da nicht die gesamte Datei auf einmal gelesen wird, wird die Speicherbelegung bei großen Dateien nicht beeinträchtigt.

$ cat a.py
import csv,itertools as it,operator as op

def grouper(iterable,n):return it.Zip_longest(*[iter(iterable)]*n)

with open('in.csv') as inf,open('out.csv','w',newline='') as outf:
 r,w=csv.reader(inf),csv.writer(outf)
 hdr=next(r)
 w.writerow(hdr)
 for row in grouper(filter(bool,map(op.methodcaller('replace','\n',''),it.chain.from_iterable(r))),len(hdr)):
  w.writerow(row)

$ python3 a.py
$ cat out.csv
playerID,yearID,gameNum,gameName,teamName,lgID,GP,startingPos
gomezle01,1933,1,Cricket,Team1,NYA,AL,1
ferreri01,1933,2,Hockey,This is Team2,BOS,AL,1
gehrilo01,1933,3,Game name is Cricket ,Team3,NYA,AL,1
gehrich01,1933,4,Hockey,Here it is Team4,DET,AL,1
dykesji01,1933,5,Game name is Hockey,Team name Team5,CHA,AL,1

Eine Annahme, die hier gemacht wird, ist das Fehlen leerer Zellen in der Eingabe-CSV.

0
kpr

Dies ist eine grundlegende Version mit einfacher Vorverarbeitung, bevor sie durch CSV gelesen wird. 

import csv

def simple_sanitize(data):
    result = []
    for i, a in enumerate(data):
        if i + 1 != len(data) and data[i + 1][0] == ',':
            a = a.replace('\n', '')
            result.append(a + data[i + 1])
        Elif a[0] != ',':
            result.append(a)
    return result

data = [line for line in open('test.csv', 'r')]
sdata = simple_sanitize(data)

with open('out.csv','w') as f:
    for row in sdata:
        f.write(row)

result = [list(val.replace('\n', '') for val in line) for line in csv.reader(open('out.csv', 'r'))]

print(result)

Ergebnis:

[['playerID', 'yearID', 'gameNum', 'gameName', 'teamName', 'lgID', 'GP', 'startingPos'], 
['gomezle01', '1933', '1', 'Cricket', 'Team1', 'NYA', 'AL', '1'], 
['ferreri01', '1933', '2', 'Hockey', 'This is Team2', 'BOS', 'AL', '1'], 
['gehrilo01', '1933', '3', 'Game name is Cricket ', 'Team3', 'NYA', 'AL', '1'], 
['gehrich01', '1933', '4', 'Hockey', 'Here it is Team4', 'DET', 'AL', '1'], 
['dykesji01', '1933', '5', 'Game name is Hockey', 'Team name Team5', 'CHA', 'AL', '1']]
0
Reck

Es könnte etwas bereinigen, aber hier ist ein Code, der das tun würde, was Sie wollen. Funktioniert für Zeilenumbrüche innerhalb eines Feldes und vor einem Komma. Wenn weitere Anforderungen erforderlich sind, könnten einige Anpassungen vorgenommen werden:

import csv

with open('data.csv', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    actual_rows = [next(reader)]
    length = len(actual_rows[0])
    real_row = []
    for row in reader:
        if len(row) < length:
            if real_row:
                real_row[-1] += row[0]
                real_row += row[1:]
            else:
                real_row = row
        else:
            real_row = row
        if len(real_row) == length:
            real_row = map(lambda s: s.replace('\n', ' '), real_row)
            # store real_row or use it as needed
            actual_rows.append(list(real_row))
            real_row = []

    print(actual_rows)

Ich speichere die korrigierten Zeilen in actual_rows, aber wenn Sie nicht in den Speicher laden möchten, verwenden Sie einfach die real_row-Variable in jeder Schleife, auf die im Kommentar hingewiesen wurde

0
damores