2015-01-29 2 views
0

Я итеративно читаю файл журнала и анализирует/извлекает данные и хотел бы добавить это к файловому кадру.Как добавить список в виде строки в pandas.DataFrame()?

df = pd.DataFrame([], columns=['item','price','qty','sold']) 
with open("mylogfile") as fh: 
    for line in fh: 
     data = extract_data(line) 
     df.append(data) ## ? 


def extract_data(line): 
    # parse and get values as a list 
    return list_values 

Update: я получаю следующее сообщение об ошибке: ValueError: Форма переданных значений (0, 0), индексы следует (4, 0)

Кроме того, Мой лог-файл содержит данные в формат

item,2,price,4.5,qty,17,sold,11 
item,12,price,14.5,qty,7,sold,4 
item,2,price,4.5,qty,13,sold,2 

Edit2: (фактический файл, и я заинтересован только в строке 'пункт'

item,2,price,4.5,qty,17,sold,11 
a,12,b,14,c,18,d,15,e16 
item,12,price,14.5,qty,7,sold,4 
x,4,y,1,z,81 
a,12,b,14,c,18,d,15,e16 
a,14,b,11,c,8,d,51,e26 
item,2,price,4.5,qty,13,sold,2 
x,14,y,11,z,8 
+0

В чем проблема? Не работает ли код выше? – Bensciens

+0

Пожалуйста, разместите данные, которые воспроизводят вашу ошибку, в основном вам нужно вернуть либо серию, либо DataFrame для добавления к существующему df, также это ужасно неэффективно, каков формат ваших данных? Вероятно, вы можете использовать любой из существующих методов для его чтения и создать df один раз: http://pandas.pydata.org/pandas-docs/stable/io.html – EdChum

ответ

2

Вот многоэтапный подход:

In [210]: 
# read in as csv, set header to None 
df = pd.read_csv(io.StringIO(t), header=None) 
df 

Out[210]: 
     0 1  2  3 4 5  6 7 
0 item 2 price 4.5 qty 17 sold 11 
1 item 12 price 14.5 qty 7 sold 4 
2 item 2 price 4.5 qty 13 sold 2 

In [213]: 
# extract the header names from the first row 
col_names = df.iloc[0][0::2] 
print(col_names) 
# extract the data columns we will use later to filter the df 
col_list = df.columns[1::2] 
col_list 
0  item 
2 price 
4  qty 
6  sold 
Name: 0, dtype: object 

Out[213]: 
Int64Index([1, 3, 5, 7], dtype='int64') 

In [214]: 
# now filter the df to the columns that actually have your data 
df = df[col_list] 
# assign the column names 
df.columns = col_names 
df 

Out[214]: 
0 item price qty sold 
0  2 4.5 17 11 
1 12 14.5 7  4 
2  2 4.5 13  2 

Так что я прочитал бы его как файл CSV, используя read_csv, не копирую свой код дословно, заменить io.StringIO(t) на пути к текстовому файлу.

UPDATE

Лучше было бы, чтобы прочитать одну строку в, извлечь имена заголовков и COLS, представляющие интерес, а затем прочитать весь файл снова, но выбрать только те столбцы, представляющие интерес и передать имя столбцов в:

In [217]: 

df = pd.read_csv(io.StringIO(t), header=None, nrows=1) 
df 
Out[217]: 
     0 1  2 3 4 5  6 7 
0 item 2 price 4.5 qty 17 sold 11 
In [218]: 

col_names = df.iloc[0][0::2] 
print(col_names) 
col_list = df.columns[1::2] 
col_list 
0  item 
2 price 
4  qty 
6  sold 
Name: 0, dtype: object 
Out[218]: 
Int64Index([1, 3, 5, 7], dtype='int64') 
In [219]: 

df = pd.read_csv(io.StringIO(t), usecols=col_list, names=col_names) 
df 
Out[219]: 
    item price qty sold 
0  2 4.5 17 11 
1 12 14.5 7  4 
2  2 4.5 13  2 
+0

Спасибо. В моем файле журнала также есть другие типы строк в csv, которые я игнорирую. Я читаю его по строкам и извлекаю только данные из интересных строк. – amehta

+0

@amehta Это действительно плохо, если честно, вы отправили вопрос и попросили о помощи, и теперь вы разместили образец реальных данных, который сильно отличается от того, что вы изначально разместили, и имеет совершенно разные характеристики. – EdChum

+0

вы можете все еще загружайте данные и просто отфильтровывайте строки, в которых нет значения «item», поэтому после загрузки просто выполните 'df [df.item! = 'item']' вам нужно снова обработать отфильтрованный df – EdChum