【问题标题】:Getting information for multiple queries across multiple .csv files跨多个 .csv 文件获取多个查询的信息
【发布时间】:2015-11-24 21:26:08
【问题描述】:

我目前正在尝试找出一种方法来获取跨多个数据集存储为 .csv 文件的信息。

上下文

就本题而言,假设我有 4 个数据集:experiment_1.csv、experiment_2.csv、experiment_3.csv 和experiment_4.csv。在每个数据集中,有 20,000 多行,每行有 80 多列。每行代表一个动物,由一个 ID 号标识,每列代表关于该动物的各种实验数据。假设每一行的动物 ID 号对于每个数据集都是唯一的,但并非在所有数据集中都是唯一的。例如 ID#ABC123 可以在experiment_1.csv、experiment_2.csv 中找到,但不是experiment_3.csv 和experiment_4.csv

问题

假设用户想要通过在所有数据集中查找每个动物的 ID # 来获取大约 100 只动物的信息。我该怎么做呢?我对编程比较陌生,我想改进。这是我目前所拥有的。

class Animal:
    def __init__(self, id_number, *other_parameters):
        self.animal_id = id_number
        self.animal_data = {}

    def store_info(self, csv_row, dataset):
        self.animal_data[dataset] = csv_row

# Main function
# ...
# Assume animal_queries = list of Animal Objects

# Iterate through each dataset csv file
for dataset in all_datasets:

    # Make a copy of the list of queries
    copy_animal_queries = animal_queries[:]

    with open(dataset, 'r', newline='') as dataset_file:
        reader = csv.DictReader(dataset_file, delimiter=',')

        # Iterate through each row in the csv file
        for row in reader:

            # Check if the list is not empty
            if animal_queries_copy:

                # Get the current row's animal id number
                row_animal_id = row['ANIMAL ID']

                # Check if the animal id number matches with a query for
                # every animal in the list
                for animal in animal_queries_copy[:]:

                    if animal.animal_id == row_animal_id:

                        # If a match is found, store the info, remove the 
                        # query from the list, and exit iterating through 
                        # each query

                        animal.store_info(row, dataset)
                        animal_list_copy.remove(animal)
                        break

            # If the list is empty, all queries were found for the current 
            # dataset, so exit iterating through rows in reader
            else:
                break

讨论

有没有更明显的方法呢?假设我现在想使用 .csv 文件,我会考虑将这些 .csv 文件转换为更易于使用的格式,例如 SQL 表(我是数据库和 SQL 的绝对初学者,所以我需要花时间学习这个)。

让我印象深刻的一件事是我必须创建animal_queries 的多个副本:每个数据集1 个,数据集中的每一行1 个(在for 循环中)。由于 1 行仅包含 1 个 ID,因此一旦找到与来自 animal_queries 的 ID 匹配的内容,我就可以提前退出循环。此外,由于已经找到该 ID,我不再需要为当前数据集的其余部分搜索该 ID,因此我将其从列表中删除,但我需要保留查询的原始副本,因为我还需要它来搜索剩余的数据集。但是,我无法在 for 循环内从列表中删除元素,因此我还需要创建另一个副本。这对我来说似乎不是最优的,我想知道我是否在错误的方向上接近这个。任何帮助将不胜感激,谢谢!

【问题讨论】:

    标签: python csv python-3.x


    【解决方案1】:

    好吧,您可以通过使用 pandas 库来大大加快这一速度。现在忽略类定义,您可以执行以下操作:

    import pandas as pd
    file_names = ['ex_1.csv', 'ex_2.csv']
    animal_queries = ['foo', 'bar'] #input by user
    
    #create list of data sets
    data_sets = [pd.read_csv(_file) for _file in file_names]
    
    #create store of retrieved data
    retrieved_data = [d_s[d_s['ANIMAL ID'].isin(animal_queries)] for d_s in data_sets]
    
    #concatenate the data
    final_data = pd.concat(retrieved_data)
    
    #export to csv
    final_data.to_csv('your_data') 
    

    这大大简化了事情。 isin 方法对在列表 animal_queires 中找到 ANIMAL ID 的每个数据帧进行切片。顺便说一句,pandas 也会帮助你处理 sql 表,所以这可能是你下去的好途径。

    【讨论】:

    • 我同意使用isin 方法可以简化程序。我现在执行的当前代码在每行读取 .csv 文件时执行搜索,并在读取所有文件后完成该过程。我相信对于 pandas,我必须完整阅读大的 .csv 文件,然后将它们放入多个大 DataFrame 中以供参考。额外的计算资源是否可以忽略不计?如果不是,那么整体权衡是否值得?我认为这是因为使用 pandas 会更实用,总体上对我来说是一次很好的学习体验。
    • 但是,我不确定如何正确连接 DataFrame,因为 .csv 文件不共享相同的标题(有些列与其他 .csv 文件重叠,有些列与我想要的相似重叠,有些有独特的列),但这可能需要我提出一个新问题。
    • 使用 pandas 肯定会获得更好的性能,而且 pandas 提供的矢量化方法比您目前的逐行迭代要快得多。如果您的文件太大以至于无法同时将它们读入内存,那么显然您需要一些不同的东西,但这将是很多动物。
    • 对于不同的标头,您可以将不同的标头连接在一起,它只会在这些标头不存在的数据中创建缺失值。或者只是事先或在程序执行期间协调标题名称。我认为您不需要为此提出问题,它是一个有据可查的软件包。
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2012-12-24
    • 2016-12-29
    • 2020-10-17
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多