2013-03-06 3 views
43

У меня есть набор данных, который выглядит следующим образом (в большинстве 5 колонка - но может быть меньше)Обработки переменного числа столбцов с пандами - Python

1,2,3 
1,2,3,4 
1,2,3,4,5 
1,2 
1,2,3,4 
.... 

Я пытаюсь использовать панд read_table, чтобы прочитать это в 5-кадровый кадр данных. Я бы хотел прочитать это без дополнительного массажа.

Если я пытаюсь

import pandas as pd 
my_cols=['A','B','C','D','E'] 
my_df=pd.read_table(path,sep=',',header=None,names=my_cols) 

Я получаю сообщение об ошибке - "имена столбцов имеют 5 полей, данные 3 поля".

Есть ли способ сделать панды заполнять NaN для недостающих столбцов при чтении данных?

ответ

50

Один из способов, который, кажется, работает (по крайней мере, в 0.10.1 и 0.11.0.dev-fc8de6d):

>>> !cat ragged.csv 
1,2,3 
1,2,3,4 
1,2,3,4,5 
1,2 
1,2,3,4 
>>> my_cols = ["A", "B", "C", "D", "E"] 
>>> pd.read_csv("ragged.csv", names=my_cols, engine='python') 
    A B C D E 
0 1 2 3 NaN NaN 
1 1 2 3 4 NaN 
2 1 2 3 4 5 
3 1 2 NaN NaN NaN 
4 1 2 3 4 NaN 

Обратите внимание, что этот подход требует, чтобы давать имена столбцов вы хочу, хотя. Не такой общий, как некоторые другие способы, но работает достаточно хорошо, когда он применяется.

+2

Спасибо! Это сработало - двигатель = 'python', кажется, ключевой. Добавление этого атрибута делает работу read_table и read_csv. –

+2

Это кажется довольно бородавчатым для меня. Добавление проблемы github: https://github.com/pydata/pandas/issues/2981 –

+9

Это работает корректно сейчас BTW без 'engine = 'python'' –

8

Мне также было бы интересно узнать, возможно ли это, из документа это, похоже, не так. Что вы могли бы, вероятно, будет читать файл строка за строкой, и сцепить каждый чтение к DataFrame:

import pandas as pd 

df = pd.DataFrame() 

with open(filepath, 'r') as f: 
    for line in f: 
     df = pd.concat([df, pd.DataFrame([tuple(line.strip().split(','))])], ignore_index=True) 

Это работает, но не в наиболее элегантный способ, я думаю ...

1

Ok. Не уверен, насколько это эффективно, но вот что я сделал. Хотелось бы услышать, есть ли лучший способ сделать это. Благодаря !

from pandas import DataFrame 

list_of_dicts=[] 
labels=['A','B','C','D','E'] 
for line in file: 
    line=line.rstrip('\n') 
    list_of_dicts.append(dict(zip(labels,line.split(',')))) 
frame=DataFrame(list_of_dicts) 
Смежные вопросы