【问题标题】:Read a csv file with multiple data sections into an addressable structure将具有多个数据部分的 csv 文件读入可寻址结构
【发布时间】:2017-02-03 19:29:47
【问题描述】:

我制作了一个csv 文件,如下所示:

现在,在我的 Python 文件中,我希望它从 food field place 列中获取数据,这只是:

a
b
c
d
e

然后我希望它只从饮料字段中获取味道等数据。

我的问题是:我如何创建一个具有类似“字段”(即:食物/饮料)并在每个字段中针对我描述的特定单元格的数据库?

【问题讨论】:

    标签: python database python-3.x csv pandas


    【解决方案1】:

    这个问题非常开放,所以我将展示两种可能的方法来将这些数据解析为可以按照您描述的方式访问的结构。


    解决方案 #1

    这段代码使用了更高级的 python 和库。它在csv 阅读器周围使用了一个生成器,以允许有效地读取数据的多个部分。然后将数据放入每个部分的pandas.DataFrame 中。每个数据框都可以在字典中访问。

    可以像这样访问数据:

    ratings['food']['taste']
    

    这将给出pandas.Series。一个常规的 python 列表可以有:

    list(ratings['food']['taste'])
    

    使用生成器将数据读取到 Pandas Dataframe 的代码:

    def csv_record_reader(csv_reader):
        """ Read a csv reader iterator until a blank line is found. """
        prev_row_blank = True
        for row in csv_reader:
            row_blank = (row[0] == '')
            if not row_blank:
                yield row
                prev_row_blank = False
            elif not prev_row_blank:
                return
    
    ratings = {}
    ratings_reader = csv.reader(my_csv_data)
    while True:
        category_row = list(csv_record_reader(ratings_reader))
        if len(category_row) == 0:
            break
        category = category_row[0][0]
    
        # get the generator for the data section
        data_generator = csv_record_reader(ratings_reader)
    
        # first row of data is the column names
        columns = next(data_generator)
    
        # use the rest of the data to build a data frame
        ratings[category] = pd.DataFrame(data_generator, columns=columns)
    

    解决方案 #2

    这是将数据读取到dict 的解决方案。可以通过以下方式访问数据:

    ratings['food']['taste']
    

    读取 CSV 到 dict 的代码:

    from collections import namedtuple
    
    ratings_reader = csv.reader(my_csv_data)
    ratings = {}
    need_category = True
    need_header = True
    for row in ratings_reader:
        if row[0] == '':
            if not (need_category or need_header):
                # this is the end of a data set
                need_category = True
                need_header = True
    
        elif need_category:
            # read the category (food, drink, ...)
            category = ratings[row[0]] = dict(rows=[])
            need_category = False
    
        elif need_header:
            # read the header (place, taste, ...)
            for key in row:
                category[key] = []
            DataEnum = namedtuple('DataEnum', row)
            need_header = False
    
        else:
            # read a row of data
            row_data = DataEnum(*row)
            category['rows'].append(row_data)
            for k, v in row_data._asdict().items():
                category[k].append(v)
    

    测试数据:

    my_csv_data = [x.strip() for x in """
        food,,
        ,,
        place,taste,day
        a,good,1
        b,good,2
        c,awesome,3
        d,nice,4
        e,ok,5
        ,,
        ,,
        ,,
        drink,,
        ,,
        place,taste,day
        a,good,1
        b,good,2
        c,awesome,3
        d,nice,4
        e,ok,5
    """.split('\n')[1:-1]]
    

    从文件中读取数据:

    with open('ratings_file.csv', 'rb') as ratings_file: 
        ratings_reader = csv.reader(ratings_file)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-11
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      相关资源
      最近更新 更多