2015-11-06 13 views
7

Mam plik CSV, który ma kilka kolumn, które najpierw ograniczam dwukropkiem (;). Jednak JEDNA kolumna jest ograniczona przez potok | i chciałbym ograniczyć tę kolumnę i utworzyć nowe kolumny.Ograniczanie konkretnej kolumny i dodawanie jej jako kolumn w pliku CSV (Python3, CSV)

Wejście:

Column 1 Column 2  Column 3 
    1   2   3|4|5 
    6   7   6|7|8 
    10   11   12|13|14 

Pożądany wyjściowa:

Column 1 Column 2  ID Age Height 
    1   2   3  4 5 
    6   7   6  7 8 
    10   11   12  13 14 

Mój kod dotąd ogranicza raz pierwszy; a następnie konwertuje do DF (będąca moją żądany format końcowy)

delimit = list(csv.reader(open('test.csv', 'rt'), delimiter=';')) 
df = pd.DataFrame(delimit) 
+1

można analizować ostatnią kolumnę i [podzielić ją] (http://stackoverflow.com/questions/14745022/pandas-dataframe-how-do- i-split-a-column-into-two) –

Odpowiedz

3

Nie pokazują dokładnie to, co dane wygląda (mówisz to jest rozdzielany średnikami, ale twoje przykłady nie mają w ogóle), ale jeśli to wygląda

Column 1;Column 2;Column 3 
1;2;3|4|5 
6;7;6|7|8 
10;11;12|13|14 

można zrobić somethi ng jak

>>> df = pd.read_csv("test.csv", sep="[;|]", engine='python', skiprows=1, 
        names=["Column 1", "Column 2", "ID", "Age", "Height"]) 
>>> df 
    Column 1 Column 2 ID Age Height 
0   1   2 3 4  5 
1   6   7 6 7  8 
2  10  11 12 13  14 

ten działa za pomocą wyrażenia regularnego separatora znaczenie „albo ; lub |” i zmuszając nazwy kolumn ręcznie.

Alternatywnie, można zrobić to w kilku krokach:

>>> df = pd.read_csv("test.csv", sep=";") 
>>> df 
    Column 1 Column 2 Column 3 
0   1   2  3|4|5 
1   6   7  6|7|8 
2  10  11 12|13|14 
>>> c3 = df.pop("Column 3").str.split("|", expand=True) 
>>> c3.columns = ["ID", "Age", "Height"] 
>>> df.join(c3) 
    Column 1 Column 2 ID Age Height 
0   1   2 3 4  5 
1   6   7 6 7  8 
2  10  11 12 13  14 
+0

Otrzymuję następujący błąd podczas próby uruchomienia drugiej połowy twojego kodu: TypeError: split() dostał nieoczekiwany argument słowa kluczowego 'expand' – user3682157

+1

@ user3682157: prawdopodobnie używając starszej wersji pandy. – DSM

0
delimit = list(csv.reader(open('test.csv', 'rt'), delimiter=';')) 

for row in delimit: 
    piped = row.pop() 
    row.extend(piped.split('|')) 

df = pd.DataFrame(delimit) 

delimit kończy się patrząc jak:

[ 
    ['1', '2', '3', '4', '5'], 
    ['6', '7', '6', '7', '8'], 
    ['10', '11', '12', '13', '14'], 
] 
0

To jest rzeczywiście znacznie szybsze w użyciu lib CSV i str.replace:

import csv 
with open("test.txt") as f: 
    next(f) 
    # itertools.imap python2 
    df = pd.DataFrame.from_records(csv.reader(map(lambda x: x.rstrip().replace("|", ";"), f), delimiter=";"), 
            columns=["Column 1", "Column 2", "ID", "Age", "Height"]).astype(int) 

Niektóre taktowania:

In [35]: %%timeit 
pd.read_csv("test.txt", sep="[;|]", engine='python', skiprows=1, 
        names=["Column 1", "Column 2", "ID", "Age", "Height"]) 
    ....: 
100 loops, best of 3: 14.7 ms per loop 

In [36]: %%timeit                
with open("test.txt") as f: 
    next(f) 
    df = pd.DataFrame.from_records(csv.reader(map(lambda x: x.rstrip().replace("|", ";"), f),delimiter=";"), 
           columns=["Column 1", "Column 2", "ID", "Age", "Height"]).astype(int) 
    ....: 
100 loops, best of 3: 6.05 ms per loop 

Można po prostu str.split:

with open("test.txt") as f: 
    next(f) 
    df = pd.DataFrame.from_records(map(lambda x: x.rstrip().replace("|", ";").split(";"), f), 
            columns=["Column 1", "Column 2", "ID", "Age", "Height"]) 
0

zorientowali się rozwiązanie dla siebie:

df = pd.DataFrame(delimit) 
s = df['Column 3'].apply(lambda x: pd.Series(x.split('|'))) 
frame = pd.DataFrame(s) 
frame.rename(columns={0: 'ID',1:'Height',2:'Age'}, inplace=True) 
result = pd.concat([df, frame], axis=1) 
Powiązane problemy