Python - 通过csv文件行值循环

问题描述:

我有一个csv文件,具有两列的以下(test.csv)。Python - 通过csv文件行值循环

338,800 
338,550 
339,670 
340,600 
327,500 
301,430 
299,350 
284,339 
284,338 
283,335 
283,330 
283,310 
282,310 
282,300 
282,300 
283,290 

从第1列中,我想读取当前行并将其与前一行的值进行比较。如果它是greaterequal,继续比较,如果当前单元格的值是smaller比前一行 - 那么我想要在同一行中的第二列的值。

接下来,我想将第1列中得到的larger value除以第2列相同单元格中的值。让我说清楚。例如在上面给出的表格中:根据我在第一列中的要求得到的较小值是327(因为327小于先前的值340) - 然后我们取500(这是对应的单元格值在第2列)。 最后我们将340除以500得到值0.68。在将值打印到控制台后,我的python脚本应该立即退出。

目前,我使用在bash下面的脚本,它工作正常

awk -F, '$1<p && $2!=0{ 
val=$2/p  
if(val>=0.8 && val<=0.9) 
    { 
     print "A" 
    } 
else if(val==0.7) 
    { 
     print "B" 
    } 
else if(val>=0.5 && val <0.7) 
    { 
     print "C" 

    } 
else if(val==0.5) 
    { 
     print "E" 
    } 
else 
    { 
     print "D" 
    } 
exit 
} 
{ 
    p=$1 
}' test.csv 

,但我想用python做到这一点,我将不胜感激的任何帮助。这里是我的方法

import csv 

f = open("test.csv", "r+") 
ff = csv.reader(f) 

previous_line = ff.next() 
while(True): 
    try: 
     current_line = ff.next() 
     if previous_line <= current_line: 
      print "smaller value" 
    except StopIteration: 
     break 
+1

您应指定你希望得到这么说,如果你得到一个不同的程序仍然会返回有用的信息,其中的例外:例如'除了StopIteration异常:' – TLOwater

+0

哦,算了吧。 OK完成。 – Mahsolid

我建议你使用内置的迭代csv.Reader的,而不是直接调用.next()。而且你的代码不应该测试正常的float值是否相等。在任何语言中,这不仅仅是一个Python的东西。此外,计算得出的值0.79将导致D,这可能不是您想要的。

from __future__ import division 
import csv 

def category(val): 
    if 0.8 < val <= 0.9: 
     return "A" 
    #Note: don't test val == 0.7: you should never test floats for equality 
    if abs(val - 0.7) < 1e-10: 
     return "B" 
    if 0.5 < val < 0.7: 
     return "C" 
    if abs(val - 0.5) < 1e-10: 
     return "E" 
    return "D" 

with open(r"E:\...\test.csv", "r") as csvfile: 
    ff = csv.reader(csvfile) 

    previous_value = 0 
    for col1, col2 in ff: 
     if not col1.isdigit(): 
      continue 
     value = int(col1) 
     if value >= previous_value: 
      previous_value = value 
      continue 
     else: 
      result = previous_value/int(col2) 
      print category(result) 
      break 

编辑响应变化的任择议定书的要求

from __future__ import division 
import csv 

def category(val): 
    if 0.8 < val <= 0.9: 
     return "A" 
    #Note: don't test val == 0.7: you should never test floats for equality 
    if abs(val - 0.7) < 1e-10: 
     return "B" 
    if 0.5 < val < 0.7: 
     return "C" 
    if abs(val - 0.5) < 1e-10: 
     return "E" 
    return "D" 

with open(r"E:\...\test.csv", "r") as csvfile: 
    ff = csv.reader(csvfile) 

    results = [] 
    previous_value = 0 
    for col1, col2 in ff: 
     if not col1.isdigit(): 
      continue 
     value = int(col1) 
     if value >= previous_value: 
      previous_value = value 
      continue 
     else: 
      result = previous_value/int(col2) 
      results.append(result) 
      print category(result) 
      previous_value = value 
    print (results) 
    print (sum(results)) 
    print (category(sum(results)/len(results))) 

我已经在你想用,因为你原来有循环重置前值逻辑猜测第一个结果就打破了。我不知道你想如何处理文件结尾。本次修订将产生以下输出:

C 
D 
A 
A 
A 
D 
[0.68, 0.7604651162790698, 0.86, 0.8820058997050148, 0.8477611940298507, 0.9129032258064517] 
4.94313543582 
A 

正如你所看到的,有一定的results超过两个值。

+0

谢谢。这很酷,并且让它成为可以接受的答案。 – Mahsolid

+0

如果我们想总结或做结果的平均值如何?我试过这样:'sum_value = sum(result)'但我发现以下错误:'TypeError:'float'对象不可迭代' – Mahsolid

+1

'sum_value = sum(result)'不会工作,因为'result'是不是花车列表,它是一个单一的值。它在每次迭代中都被赋予'for'循环。要做你想做的事情,把每个计算结果的值存储在一个名为'results'的列表中,然后在break之前调用sum(results)。 – BoarGules

col_1 = [] 
col_2 = [] 
with open("test.csv", "r+") as f: 
    for elem in f.readlines(): 
     col_1.append(float(elem.split(",")[0])) 
     col_2.append(float(elem.split(",")[1])) 

condition = True 
i=0 
while condition: 
    if (col_1[i+1]-col_1[i]<0): 
     print col_1[i]/col_2[i+1] 
     condition = False 
    i+=1 

如果它是一个.csv文件,使用熊猫可以给你更多的控制。

import numpy as np 
import pandas as pd 

pd.read_csv("filename.csv") # to read a .csv file into a dataframe 

但是,对于这个例子,我没有使用pd.read_csv()函数。相反,我创建从2D numpy的阵列,像这样一个数据帧,

dataframe = pd.DataFrame(np.array([[338,800], 
    [338,550], 
    [339,670], 
    [340,600], 
    [327,500], 
    [301,430], 
    [299,350], 
    [284,339], 
    [284,338], 
    [283,335], 
    [283,330], 
    [283,310], 
    [282,310], 
    [282,300], 
    [282,300], 
    [283,290]])) 

现在,我有一个数据帧的对象,我可以操作它,就像在Python其他对象类型。我可以调用熊猫特定函数来处理数据帧以获得我想要的结果。

def compare_and_divide(df): 
    for i in range(len(df)-1): 
     # df[0] for all values in col 0 .iloc[i] for value in row 
     if df[0].iloc[i+1] >= df[0].iloc[i]:         
      continue  
     else: 
      df[0].iloc[i+1] = df[0].iloc[i] 

    return df[0].div(df[1]) # .div() function to divide values in col 0 by col 1 

compare_and_divide(dataframe) 

0  0.422500 
1  0.614545 
2  0.505970 
3  0.566667 
4  0.680000 # 340/500 value mentioned in the question 
5  0.790698 
6  0.971429 
7  1.002950 
8  1.005917 
9  1.014925 
10 1.030303 
11 1.096774 
12 1.096774 
13 1.133333 
14 1.133333 
15 1.172414 
dtype: float64