繁体   English   中英

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

[英]Extracting multiple tables/datasets from csv

我有一个小的 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 行下方追加行,如果一行没有数据,则停止追加。 我怎样才能做到这一点? 我也明白在数据帧中使用循环不是最好的解决方案,欢迎使用替代解决方案。

这是我会做的:

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]

如果我理解正确,您可以在使用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

数据文件内容:

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM