2

我有一个 .csv 文件,其中 2+ 个空行代表一个新数据部分。但是不知道每个部分有多少行。有没有办法直接读取熊猫数据框并在前 2 个以上的空白行处停止?

数据如下(来自 Google 趋势结果的 .csv 文件,此处被截断)。

Web Search interest: zts
Worldwide; 2004 - present

Interest over time
Week,zts
2004-01-04 - 2004-01-10,0
2004-01-11 - 2004-01-17,80


Top regions for zts
Region,zts
Slovakia,100
Slovenia,23


Top cities for zts
City,zts
Bratislava (Slovakia),100
Wroclaw (Poland),39



Top searches for zts
focus zts,100
ford zts,90



Rising searches for zts
2002 focus zts,Breakout
battery tester,Breakout

现在,我使用csv.reader()并循环遍历所有行,并保留与第一列中的日期正则表达式匹配且有两列的行。但这似乎很骇人听闻。

如果我使用类似的东西pandas.read_csv(input_file, header=4)(然后稍后使用日期正则表达式来查找正确的部分),那么当最后一部分有三列时它会失败(这里没有,但它可以)。

有没有办法在没有先验知道行数的情况下阻止我pandas.read_csv()在第一个块之后?理想情况下,我想将此 .csv 解析为五个数据帧(每个数据部分一个),但此时我很高兴抓住第一部分。

4

2 回答 2

1

Here's my solution to real problem, which is that I should interpret my one .csv file as several .csv files and do this split outside of pandas.

import csv

section = 1
line = 1

output_root = 'C:/Users/richard/Downloads/out'
input_file = 'C:/Users/richard/Downloads/in.csv'

input = open(input_file, 'rb')
reader = csv.reader(input)

for row in reader:
    if any(row) & (line == 1):
        output_file = output_root + '_' + str(section) + '.csv'
        output = open(output_file, 'wb')
        writer = csv.writer(output)
        writer.writerow(row)
        line += 1
    elif any(row) & (line > 1):
        writer.writerow(row)
        line += 1
    elif (line > 1):
        output.close()
        section += 1
        line = 1

output.close()
input.close()
于 2013-08-28T16:59:31.877 回答
1

您也可以使用正则表达式。它们在这种情况下工作得很好。

import re
from cStringIO import StringIO

csv1 = """right,top,bottom
4,5,6
6,7,8
"""

csv2 = """up,down,left
1,2,3
7,6,5
"""

csv3 = """a,b,c
1,2,3
4,5,6
"""

join_n = randint(2, 6, size=2)
raw = [csv1, csv2, csv3]
csvs = []

for csv, n in zip(raw, join_n):
    csvs.append(csv + '\n' * n)

csvs.append(csv3)
csvs = ''.join(csvs)

splitsville = re.split('\n{2,}', csvs)

dfs = []

for sp in splitsville:
    dfs.append(read_csv(StringIO(sp)))


final_df = concat(dfs, axis=1)

print final_df

产量:

   right  top  bottom  up  down  left  a  b  c
0      4    5       6   1     2     3  1  2  3
1      6    7       8   7     6     5  4  5  6

注意:您不一定必须concat使用listof DataFrames,但通常这是有用的下一步,因此您不必继续对 a listof DataFrames 进行操作。

于 2013-08-28T17:54:09.707 回答