从csv中提取多个表/数据集

时间:2020-01-08 19:34:06

标签: python loops

我有一个很小的csv文件,其中包含每个不超过50行的表/数据集,并且每个表/数据集之间用空白行分隔。该文件的外观示例:

Info_header 1
Info_header 2
NaN
Title1, Title2
Column1,Column2,Column3,Column4,Column5,Column6,Column7,Column8
Steve,Indiana,0,0,2,1,2,5
Megan,New York,34,0,0,5,3,2
...
NaN
-Total-,,34,0,2,6,5,7
NaN
Title3,Title4
ColumnA,ColumnB,ColumnC,ColumnD,ColumnE,ColumnF,ColumnG,ColumnH
...

行和列的大小更改确实发生了变化。具有单个NaN的行表示空白行。由于表是已命名的,因此我计划使用的循环需要在具有表标题的行下方开始:

df = read_csv('data.csv')

start_value = df.loc[(df[0] == "Title1")
                     & (df[1] == "Title2")]

start_value = (start_value.index + 1)

# my loop:

empty_list = []
for index, row in df.loc[start_value[0]].iteritems():
    if pd.isnull(row[1]):
        empty_list.append(df[row])
    else:
        break

我的逻辑是,如果Title1和Title2符合我的条件,则在Title行下方追加行,并在行中没有数据时停止追加。我怎样才能做到这一点?我也了解在数据帧中使用循环并不是最好的解决方案,欢迎使用替代解决方案。

3 个答案:

答案 0 :(得分:1)

这就是我要做的:

from io import StringIO
import pandas as pd

with open('data.csv') as f:
    block = ''
    for line in f:
        block += line
        if not line[:-1]:
            if len(block.splitlines()) > 3:
                print(pd.read_csv(StringIO(block), skiprows=1))
            block = ''

如果将NaN替换为空白行,并且第二块用一些数据完成,则将结果应用于示例数据时

#   Column1   Column2  Column3  ...  Column6  Column7  Column8
# 0   Steve   Indiana        0  ...        1        2        5
# 1   Megan  New York       34  ...        5        3        2

# [2 rows x 8 columns]

#    ColumnA  ColumnB  ColumnC  ...  ColumnF  ColumnG  ColumnH
# 0        1        2        3  ...        6        7        8

# [1 rows x 8 columns]

答案 1 :(得分:0)

如果我理解正确,则可以使用re模块(如果您事先知道标题)来“清理”数据。

例如(Regex101):

txt = '''Info_header 1
Info_header 2

Title1, Title2
Column1,Column2,Column3,Column4,Column5,Column6,Column7,Column8
Steve,Indiana,0,0,2,1,2,5
Megan,New York,34,0,0,5,3,2

-Total-,,34,0,2,6,5,7

Title3,Title4
ColumnA,ColumnB,ColumnC,ColumnD,ColumnE,ColumnF,ColumnG,ColumnH
0,1,2,3,4,5,6,7
'''

import re
from io import StringIO

df1 = pd.read_csv( StringIO(re.findall(r'^Title1.*?Title2(.*?)(?:\n\n|\Z)', txt, flags=re.M|re.S)[0]) )
df2 = pd.read_csv( StringIO(re.findall(r'^Title3.*?Title4(.*?)(?:\n\n|\Z)', txt, flags=re.M|re.S)[0]) )

print(df1)
print()
print(df2)

打印:

  Column1   Column2  Column3  Column4  Column5  Column6  Column7  Column8
0   Steve   Indiana        0        0        2        1        2        5
1   Megan  New York       34        0        0        5        3        2

   ColumnA  ColumnB  ColumnC  ColumnD  ColumnE  ColumnF  ColumnG  ColumnH
0        0        1        2        3        4        5        6        7

答案 2 :(得分:-1)

数据文件内容:

Title 1,Title 2
Column1,Column2,Column3,Column4,Column5,Column6,Column7,Column8
Steve,Indiana,0,0,2,1,2,5
Megan,New York,34,0,0,5,3,2

Title 3,Title 4
ColumnA,ColumnB,ColumnC,ColumnD,ColumnE,ColumnF,ColumnG,ColumnH
val 1 A, val 1 B, val 1 C, val 1 D, val 1 E, val 1 F, val 1 G, val 1 H
val 2 A, val 2 B, val 2 C, val 2 D, val 2 E, val 2 F, val 2 G, val 2 H

代码:

from io import StringIO

import pandas as pd

with open('../resources/temp_in.txt') as in_file:
    file_contents = in_file.read()

tables = []

for curr_str in file_contents.split('\n\n'):
    table_title, table_data = curr_str.split('\n', maxsplit=1)
    table_data = pd.read_csv(StringIO(table_data))
    print(f"{table_title}\n{table_data}\n")
    tables.append((table_title, table_data))

输出:

Title 1,Title 2
  Column1   Column2  Column3  Column4  Column5  Column6  Column7  Column8
0   Steve   Indiana        0        0        2        1        2        5
1   Megan  New York       34        0        0        5        3        2

Title 3,Title 4
   ColumnA   ColumnB   ColumnC  ...   ColumnF   ColumnG   ColumnH
0  val 1 A   val 1 B   val 1 C  ...   val 1 F   val 1 G   val 1 H
1  val 2 A   val 2 B   val 2 C  ...   val 2 F   val 2 G   val 2 H

[2 rows x 8 columns]
相关问题