Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 比循环整个文件更好的正则表达式实现?_Python_Regex_Python 3.x_Shell_Text - Fatal编程技术网

Python 比循环整个文件更好的正则表达式实现?

Python 比循环整个文件更好的正则表达式实现?,python,regex,python-3.x,shell,text,Python,Regex,Python 3.x,Shell,Text,我有这样的文件: # BJD K2SC-Flux EAPFlux Err Flag Spline 2457217.463564 5848.004 5846.670 6.764 0 0.998291 2457217.483996 6195.018 6193.685 6.781 1 0.998291 2457217.504428 6396.612 6395.278 6.790 0 0.998292 2457217.524861 6220.890 6219.556 6.782 0

我有这样的文件:

#     BJD     K2SC-Flux EAPFlux   Err  Flag Spline
2457217.463564 5848.004 5846.670 6.764 0 0.998291
2457217.483996 6195.018 6193.685 6.781 1 0.998291
2457217.504428 6396.612 6395.278 6.790 0 0.998292
2457217.524861 6220.890 6219.556 6.782 0 0.998292
2457217.545293 5891.856 5890.523 6.766 1 0.998292
2457217.565725 5581.000 5579.667 6.749 1 0.998292
2457217.586158 5230.566 5229.232 6.733 1 0.998292
2457217.606590 4901.128 4899.795 6.718 0 0.998293
2457217.627023 4604.127 4602.793 6.700 0 0.998293
我需要查找并计数带有Flag=1的行。(第五栏)我就是这样做的:

foundlines=[]
c=0
import re
with open('examplefile') as f:
    for index, line in enumerate(f):
        try:
            found = re.findall(r' 1 ', line)[0]
            foundlines.append(index)
            print(line)
            c+=1
        except:
            pass
print(c)

在Shell中,我只需执行
grep“1”examplefile | wc-l
,这比上面的Python脚本要短得多。python脚本可以工作,但我感兴趣的是,是否有比上面的脚本更短、更紧凑的方法来完成任务?我更喜欢Shell的简短,所以我希望在Python中有类似的东西。

您的Shell实现可以更简短,
grep
-c
选项来获取计数,无需匿名管道和
wc

grep -c " 1 " examplefile

shell代码只需获取模式
1
所在的行数,但是Python代码还保留了模式匹配所在行的索引列表

只需获得行数,就可以使用
sum
和genexp/list comprehension,也不需要Regex;简单字符串
\uuuu包含\uuuu
检查将执行以下操作,因为字符串是可编辑的:

with open('examplefile') as f:
    count = sum(1 for line in f if ' 1 ' in line)
    print(count)  
如果您也想保留索引,您可以坚持您的想法,只需将
re
test替换为
str
test:

count = 0
indexes = []
with open('examplefile') as f:
    for idx, line in enumerate(f):
        if ' 1 ' in line:
            count += 1
            indexes.append(idx)

此外,做一个简单的
Exception
几乎总是一个坏主意(至少你应该使用
Exception
来省略
SystemExit
键盘中断
类似异常),只捕获你知道可能引发的异常

此外,在解析结构化数据时,您应该使用特定的工具,例如此处
csv.reader
,以空格作为分隔符(
line.split(“”)
在这种情况下也应该这样做),并根据索引4进行检查将是最安全的(请参阅)。使用第行中的
“1”测试,如果任何其他列包含
1
,则会产生误导性结果

考虑到上述情况,以下是使用
awk
匹配第5个字段的shell方式:

awk '$5 == "1" {count+=1}; END{print count}' examplefile

如果您有CSV数据,您可以使用
CSV
模块:

import csv

with open('your file', 'r', newline='', encoding='utf8') as fp:
    rows = csv.reader(fp, delimiter=' ')

    # generator comprehension
    errors = (row for row in rows if row[4] == '1')

for error in errors:
    print(error)
最短代码 在某些特定前提下,这是一个非常简短的版本:

  • 您只需要像您的grep调用一样计算发生次数
  • 保证每行只有一个
    “1”
  • “1”
    只能出现在所需的列中
  • 你的文件很容易放入内存
请注意,如果不满足这些前提条件,可能会导致内存问题或返回误报

print(open("examplefile").read().count(" 1 "))
简单多用,略长 当然,如果你对这些台词有兴趣,我推荐熊猫:

df = pandas.read_table('test.txt', delimiter=" ",
                       comment="#",
                       names=['BJD', 'K2SC-Flux', 'EAPFlux', 'Err', 'Flag', 'Spline'])
要获取标志为1的所有行,请执行以下操作:

flaggedrows = df[df.Flag == 1]
返回:

            BJD  K2SC-Flux   EAPFlux    Err  Flag    Spline
1  2.457217e+06   6195.018  6193.685  6.781     1  0.998291
4  2.457218e+06   5891.856  5890.523  6.766     1  0.998292
5  2.457218e+06   5581.000  5579.667  6.749     1  0.998292
6  2.457218e+06   5230.566  5229.232  6.733     1  0.998292
要计算它们:

print(len(flaggedrows))

返回4

因为代码工作,您应该考虑将此发布到AT。但是,很明显,在空格之间查找
1
不需要正则表达式,如果行中有“1”,请使用
。Python中的大多数内容可以放在一行上,但这会严重损害可读性。你确定尺寸对你来说是唯一重要的东西吗?如果你喜欢短的,就用shell。是的,如果可读性比我不介意长的话。好的,我将重新考虑shell实现<代码>。。。如果第
行中的“1”是不可靠的。@Tomalak我承认;)按照字面上的例子。那么你至少应该警告误报的风险。这里是否存在误报的危险,正如这里提到的@heemayl我添加了警告和更好的答案