2013-09-11 3 views
0

У вас возникли проблемы с кодом, который должен считывать значения, разделенные запятыми, из .txt-файла, сортировать по массивам на основе негатива, а затем обрабатывать данные. Вот код, а затем 2 .txt файлов, первый работает, но второй один неPython Index за пределами диапазона по потоку денежных средств

#check python is working 
print "hello world" 

#import ability to plot and use matrices 
import matplotlib.pylab as plt 
import numpy as np 

#declare variables 
posdata=[] 
negdata=[] 
postime=[] 
negtime=[] 
interestrate=.025 


#open file 
f= open('/Users/zacharygastony/Desktop/CashFlow_2.txt','r') 
data = f.readlines() 

#split data into arrays 
for y in data: 
    w= y.split(",") 
    if float(w[1])>0: 
     postime.append(int(w[0])) 
     posdata.append(float(w[1])) 
    else: 
     negtime.append(int(w[0])) 
     negdata.append(float(w[1])) 

print "Inflow Total: ", posdata 
print "Inflow Time: ", postime 
print "Outflow Total: ", negdata 
print "Outflow Time: ", negtime 

#plot the data 
N=len(postime) 
M=len(negtime) 

ind = np.arange(N+M) # the x locations for the groups 
width = 0.35  # the width of the bars 

fig, ax = plt.subplots() 
rects1 = ax.bar(ind, posdata+negdata, width, color='r') 

# add some 
ax.set_ylabel('Cash Amount') 
ax.set_title('Cash Flow Diagram') 
ax.set_xlabel('Time') 

plt.plot(xrange(0,M+N)) 
plt.show()' 

.txt 1_ _ ____

0,3761.97 
1,-1000 
2,-1000 
3,-1000 
4,-1000 

.txt 2_ _ __ _ _

0,1000 
1,-1000 
2,1000 
3,-1000 

Моя ошибка заключается в следующем:

>>> runfile('/Users/zacharygastony/cashflow.py', wdir=r'/Users/zacharygastony') 
hello world 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/zacharygastony/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile 
execfile(filename, namespace) 
    File "/Users/zacharygastony/cashflow.py", line 24, in <module> 
    if float(w[1])>0: 
IndexError: list index out of range 
+0

Как примечание стороны, если вы с трудом время чтения и разбора CSV файлов (или, на самом деле, даже если вы не), вы должны рассмотреть возможность использования либо 'csv' модуль в стандартную библиотеку и/или функцию CSV numpy вместо того, чтобы пытаться сделать это вручную. – abarnert

ответ

0

Одна ошибка, что я могу определить это с "если поплавок (ш [1])> 0:" - это shoudl принять во внимание, что ж [1 ] будет набор из двух значений, разделенных пробелом. Вот как w будет выглядеть для второго файла: «['0', '1000 1', '-1000 2', '1000 3', '-1000 \ n']". Таким образом, w [1] будет «1000 1», и принятие поплавка для этого значения будет ошибкой. Итак, если вы действительно хотите получить доступ ко второму элементу, тогда один из способов - разбить его, используя разделитель по умолчанию и выбрать первый (или второй). Что-то вроде: «if float ((w [1] .split()) [0])> 0:".

+0

выясняет причину, по которой он не будет работать, потому что у моего .txt-файла были дополнительные пустые строки внизу, которые я не видел. Можно ли проверить мой оператор «if», если он первый, и если да, игнорировать эти строки? –

+0

Это перешло мне в голову, но потом, когда я был двумя словами, я не пошел туда! Чтобы игнорировать эти строки, мы всегда можем проверить, равна ли длина w 0. Что-то вроде: «if len (w) == 0: continue» –

+0

Подумайте об этом, так как вы используете w [1], вы вероятно, следует проверить, что w имеет по крайней мере два элемента: «если len (w) <2: continue» –

0

Без фактических файлов (или, что лучше, SSCCE, которые демонстрируют ту же проблему), нет никакого способа точно знать, что происходит не так. Когда я запускаю ваш код (просто изменяя hardcoded pathname) с вашими точными данными, все работает нормально.

Но если if float(w[1])>0: поднимает IndexError, ясно, что w имеет только 0 или 1 элемент.

С w пришел с w= y.split(","), это означает, что y не содержит никаких запятых.

С y есть каждая строка из вашего файла, одна из линий в нем не содержит никаких запятых.

Какая линия? Ну, ни один из них в примере, который вы дали.

Скорее всего, ваш реального файл имеет что-то вроде пустой строки в конце, так w заканчивается в виде списка одного элемента [''].

Или ... может быть, что 2______ на самом деле является линией заголовка в верхней части файла, и в этом случае w закончится как ['2______'].

Или фактический файл, с которым вы работаете, является более длинным, отредактированным вручную файлом, где вы где-то опечатали, например 4.1000 вместо 4,1000.

Или ...

На самом деле выяснить проблему, а не просто угадать, вам нужно отлаживать вещи, используя отладчик или интерактивный визуализатор, или просто добавить print заявления регистрировать все промежуточные значения:

print(y) 
w= y.split(",") 
print(w) 
w1 = w[1] 
print(w1) 
f = float(w1) 
print(f) 
if f>0: 
    # ... 

Таким образом, фактическая проблема заключается в пустые строки в конце файла. Как вы можете с этим справиться?

Вы можете пропустить пустые строки или пропустить строки без достаточной запятой или просто обработать исключение и продолжить.

Например, давайте пропустим пустые строки. Обратите внимание, что readlines оставляет символы новой строки на конце, поэтому они фактически не будут пустым, они будут '\n' или, может быть, в зависимости от вашей платформы и версии Python, что-то вроде '\r\n'. Но на самом деле, вы, вероятно, хотите пропустить линию с ничего, кроме пробелов, верно? Итак, давайте просто называть strip на него, и если результат пуст, пропустите строку:

for y in data: 
    if not y.strip(): 
     continue 
    w = y.split(",") 

Если вы предпочитаете предварительной обработки вещей, вы можете:

data = f.readlines() 
data = [line for line in data if line.strip()] 

Проблема с это то, что помимо чтения во всем файле и поиска новых строк для разделения и создания большого списка (все, что вы уже делали, просто позвонив readlines), вы тоже также теперь перебираете весь снова перечислите и создайте еще один список. И все это, прежде чем вы начнете. И нет оснований для этого.

Вы можете просто перебирать файл, не нажимая на него readlines, который будет захватывать линии по мере необходимости.

И вы можете использовать выражение генератора вместо понимания списка для «препроцесса» без фактического выполнения работы вверх. Итак:

data = (line for line in f if line.strip()) 
+0

выясняет причину, по которой он не работает, потому что у моего .txt-файла были дополнительные новые строки внизу, я не видел , Можно ли предварительно написать предварительный просмотр и удалить пустые строки? –

+0

@ ZacharyGastony: Конечно, есть. Но почему бы просто не сделать это на лету? Позвольте мне изменить свой ответ, чтобы показать вам, что я имею в виду. – abarnert

Смежные вопросы