2015-11-06 7 views
7

Ho un file csv che ha diverse colonne che prima delimitano con due punti (;). Tuttavia, UNA colonna è delimitata da un tubo | e vorrei delimitare questa colonna e creare nuove colonne.Delimitare una colonna specifica e aggiungerle come colonne in CSV (Python3, CSV)

ingresso:

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

output desiderato:

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

Il mio codice finora delimita la prima volta da; e poi converte a DF (che è il mio formato finale desiderato)

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

è possibile analizzare l'ultima colonna e [dividerlo] (http://stackoverflow.com/questions/14745022/pandas-dataframe-how-do- i-split-a-column-in-two) –

risposta

3

Non hai mostrare esattamente ciò che i dati sembra (si dice è delimitato da punti e virgola, ma i tuoi esempi non hanno alcuna), ma se sembra

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

si potrebbe fare somethi ng come

>>> 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 

Questo funziona utilizzando un significato separatore regex "sia ; o |" e costringendo i nomi di colonna manualmente.

In alternativa, si potrebbe fare in pochi passi:

>>> 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

Viene visualizzato il seguente errore quando si tenta di eseguire la seconda parte del codice: TypeError: split() ottenuto un argomento parola chiave inaspettato 'expand' – user3682157

+1

@ user3682157: probabilmente utilizzando una versione precedente di panda. – 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 finisce per assomigliare:

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

In realtà è molto più veloce di utilizzare il lib csv e 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) 

Alcuni timing:

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 

Si potrebbe semplicemente 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

capito una soluzione per me:

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) 
Problemi correlati