如果存在特定数据,则使用Python解析CSV文件

如果存在特定数据,则使用Python解析CSV文件,python,csv,Python,Csv,数据文件如下所示: "2015","21","2","RICK","D","w","1","1","f","8","","00","","","","","S" "2015","56","5","RICK","E","g","1","1","k","8","","15","","","","","F" 仅当最后一个字段为“S”时,我需要将第三个字段添加到总计中。否则,将跳过该行 我尝试导入CSV并使用以下内容: for line in csv.reader(file, quotechar='"

数据文件如下所示:

"2015","21","2","RICK","D","w","1","1","f","8","","00","","","","","S"
"2015","56","5","RICK","E","g","1","1","k","8","","15","","","","","F"
仅当最后一个字段为“S”时,我需要将第三个字段添加到总计中。否则,将跳过该行

我尝试导入CSV并使用以下内容:

for line in csv.reader(file, quotechar='"', delimiter=',', quoting=csv.QUOTE_ALL, skipinitialspace=True):
if line[16] == "S":
    total = total + line[2]
['"2015"', '"43"', '"2"', '"ZETA"', '"W"', '"x"', '"1"', '"1"', '"d"', '"2"', '""', '"31"', '""', '""', '""', '""', '"N"']
这告诉我“索引器:列表索引超出范围”。也许有更好的办法。我认为导入CSV将为我完成大部分工作。最好的办法是什么?在这一点上,我会采取任何可行的方式

打印一行将显示以下内容:

for line in csv.reader(file, quotechar='"', delimiter=',', quoting=csv.QUOTE_ALL, skipinitialspace=True):
if line[16] == "S":
    total = total + line[2]
['"2015"', '"43"', '"2"', '"ZETA"', '"W"', '"x"', '"1"', '"1"', '"d"', '"2"', '""', '"31"', '""', '""', '""', '""', '"N"']
您可以轻松做到这一点:

In [52]:
# read the csv into a dataframe
df = pd.read_csv(r'c:\data\sample.txt', quotechar="\"", header=None)
df
Out[52]:
     0   1   2     3  4  5   6   7  8   9   10  11  12  13  14  15 16
0  2015  21   2  RICK  D  w   1   1  f   8 NaN   0 NaN NaN NaN NaN  S
1  2015  56   5  RICK  E  g   1   1  k   8 NaN  15 NaN NaN NaN NaN  F
In [55]:
# we can filter the values and then call count()
df.loc[df[16] == 'S',16].count()
Out[55]:
1
In [56]:
# we can also show the count for all unique values
df[16].value_counts()
Out[56]:
S    1
F    1
dtype: int64

=
将右侧操作数的值赋值给左侧操作数

如果第[16]=“S”行:
应该是
如果第[16]=“S”行:

根据您的代码:

import csv
file = open("sample.csv")
total = 0
for line in csv.reader(file, quotechar='"', delimiter=',', quoting=csv.QUOTE_ALL, skipinitialspace=True):
    if line[16] == "S":
        total = total + int(line[2])

file.close()
print "total:{}".format(total)
hzhang@dell-work ~ $ python test.py 
total:2
请确保您的所有输入行都有17个字段,并在汇总前转换每个字段的第3列

检查哪些行没有17个字段。 如果len(行)!=17:
打印行

可以考虑使用负数组索引来访问数组末尾的项:

total = 0
for line in cvs.reader(...):
    if line[-1] == "S":
        total += int(line[2])

文件可能没有一致的17列。发生这种情况的一种方法是在文件末尾有一个额外的换行符

下面是如何检测导致问题的线路

reader = csv.reader(file, quotechar='"', delimiter=',', quoting=csv.QUOTE_ALL, skipinitialspace=True)
for line_num, line in enumerate(reader, start=1):
    try:
        if line[16] == "S":
            total = total + line[2]
    except IndexError:
        # show offending line
        print(line_num, line)
        # reraise to halt execution
        raise

尝试打印
并查看您得到的结果文件是否可能有一个没有字段的最终(空)行?也许:
如果行和行[16]='S':…
我添加了一条打印行。谢谢。我发现您的
阅读器
对象在数据中保留引号很有趣。我认为
quoting=csv.QUOTE\u ALL
是指向
csv.writer
对象的指令,被
csv.reader
对象忽略。这里有些可疑。这将是一个
语法错误。我猜OP的原始代码没有这个错误。纠正Steven,我的输入错误。很抱歉海防站的接球不错!我100%试过你的代码。我仍然得到:if行[16]=“S”:indexer:list索引超出范围。若你们打印行,它看起来像我的吗?你们可能有1)空行2)行包含多于或少于17列。如果输入是您在问题“问题的根本原因是假设行已在空白处拆分”中提供的2行,则代码有效。您根据什么提出该声明?我没看见。我看见了,是的,我急忙把答案拿出来。我要换个说法。该死,情况更糟了。我的答案是基于我的错误。不过我对负指数的建议是:)我会编辑我的答案。在这种情况下使用负指数可能会掩盖数据中的错误。一条只有4个字段的线会静静地通过;添加或减去列是暴露解析非自描述性数据的脆弱性的一种很好的方法。在我自己的经验中,数据更可能增长一列而不是收缩一列,感谢您分享您的经验。第[2]行是字符串,您必须先将其转换为整数,然后再求和up@haifzhan:很公平,但这不是问题所在。没错。HaihanZAN编写了好的代码,但是我不知怎么在我的CSV文件的150000行中间加了2个空格。您的代码发现了错误,我已将其添加到程序的开头,因此错误行将不会再次导致此问题。谢谢你们两位!!!