我有一个数据文件,我需要跳过某些行。
(1 1),skip,this
skip,this,too
1,2,3
4,5,6
7,8,9
10,11,12
(1 2),skip,this
skip,this,too
...
他们会在每4个数据条目后重复播放。我尝试了这篇文章Pandas: ignore all lines following a specific string when reading a file into a DataFrame中的内容,但是没有任何内容被跳过,而是将数据框转换为MultiIndex。
我尝试使用startswith()
进行循环并附加到列表中,但是,数据正在输入到单个列中。
我正在尝试获取此输出:
1,2,3
4,5,6
7,8,9
10,11,12
有多个文件,每个文件包含超过7M行。我正在寻找一种快速,内存有效的方法来实现这一目标。
我尝试的是创建一个列表以跳过行0,1
,然后再次6, 7
。是否有可能实现这一目标?
答案 0 :(得分:1)
我的建议是预先擦洗文件:
with open("file.csv") as rp, open("outfile.csv", 'w') as wp:
for line in rp:
if 'skip' not in line:
wp.write(line)
答案 1 :(得分:1)
假设您想要在两行之后跳过四行的部分,只需跳过两行并从csv阅读器中获取一行四行:
from itertools import islice, chain
import pandas as pd
import csv
def parts(r):
_, n = next(r), next(r)
while n:
yield islice(r, 4)
_, n = next(r, ""), next(r, "")
_, n = next(r, ""), next(r, "")
with open("test.txt")as f:
r = csv.reader(f)
print(pd.DataFrame(list(chain.from_iterable(parts(r)))))
输出:
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
3 10 11 12
或者将链对象传递给pd.DataFrame.from_records
:
with open("test.txt")as f:
r = csv.reader(f)
print(pd.DataFrame.from_records(chain.from_iterable(parts(r))))
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
3 10 11 12
使用消耗配方使用函数跳过行的更通用的方法:
from itertools import islice, chain
from collections import deque
import pandas as pd
import csv
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
def parts(r, sec_len, skip):
consume(r,skip)
for sli in iter(lambda: list(islice(r, sec_len)), []):
yield sli
consume(r, skip)
with open("test.txt")as f:
r = csv.reader(f)
print(pd.DataFrame.from_records((chain.from_iterable(parts(r, 4, 2)))))
最后一个选项是写入StringIo对象并传递:
from io import StringIO
def parts(r, sec_len, skip):
consume(r, skip)
for sli in iter(lambda: list(islice(r, sec_len)), []):
yield "".join(sli)
consume(r, skip)
with open("test.txt")as f:
so = StringIO()
so.writelines(parts(f, 4, 2))
so.seek(0)
print(pd.read_csv(so, header=None))
答案 2 :(得分:1)
一种方法是生成要跳过的行号列表,因此请在此处使用方法确定文件中的行数:Count how many lines are in a CSV Python?
然后执行以下操作:
In [16]:
import io
import pandas as pd
t="""(1 1),skip,this
skip,this,too
1,2,3
4,5,6
7,8,9
10,11,12
(1 2),skip,this
skip,this,too"""
# generate initial list, using 10 her but you can get the number of rows using another metho
a = list(range(10))
# generate the pairs of rows to skips in steps
rows = sorted(a[::6] + a[1::6])
# now read it in
pd.read_csv(io.StringIO(t), skiprows=rows, header=None)
Out[16]:
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
3 10 11 12
答案 3 :(得分:1)
由于你有一个重复模式(折腾两行,保持四行),我可能会这样做:
from io import BytesIO
with open("skipper.csv", "rb") as fp:
lines = (line for i,line in enumerate(fp) if i % 6 >= 2)
df = pd.read_csv(BytesIO(b''.join(lines)), header=None)
给了我
>>> df
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
3 10 11 12
答案 4 :(得分:-1)
我会想要动态地进行过滤:
import subprocess
import pandas as pd
cmd = "awk '(NR - 1) % 6 > 1' test.csv"
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
df = pd.read_csv(proc.stdout, header=None)
awk命令将跳过每组6中的前两行。由于过滤是在流式基础上完成的,因此这是非常高效的内存,并且由于过滤是在单独的过程中完成的,因此它将是也很快。