【问题标题】:How can I efficiently add data from dictionaries to a dataframe?如何有效地将字典中的数据添加到数据框中?
【发布时间】:2019-08-24 21:12:46
【问题描述】:

在 for 循环中,我使用从函数返回的字典填充数据帧。也许我没有使用正确的术语进行搜索,或者我解决此问题的方法是错误的,但我无法在网上找到适用的解决方案。我认为我目前这样做的方式非常低效。

我对 Pandas 相当缺乏经验 - 我尝试了一些尝试使用合并方法,以及 concat、append 和 remove_duplicates 的一些组合,但我还没有完全管理我想要的。

我目前的解决方案是遍历字典项:

for company in Company.instances:
    for resource in company.resources:
        for product in resource["product"]:
            my_dictionary = my_function("with varying args per company/product")

            # Remove None values from my_dictionary
            my_dictionary = {k: v for k, v in my_dictionary.copy().items() if v is not None}

            # TODO speed this up
            if len(my_dictionary) > 0:
                df = Company.products[product]["current"]
                for subproduct, value in my_dictionary.items():
                    df.loc[
                        (df["product"] == product) &
                        (df["subproduct"] == subproduct),
                        company.name
                    ] = value

注意事项:

Company.products[product]["current"] 的 Company 类中的每个数据帧都使用以下格式的每个数据帧一个产品进行初始化:

        product     subproduct  company1    company2
0       a           1
1       a           2
2       a           3
3       a           4
4       a           5

字典键是指子产品列。数据框中的每个公司列可以有两个或多个字典 - 例如:

"""
if my_function returns this dict for company1:
{'1': 'alpha', '2': 'bravo', '3': 'charlie'}

desired:
        product     subproduct  company1    company2
0       a           1           alpha
1       a           2           bravo
2       a           3           charlie       
3       a           4                       
4       a           5

followed by this dict also for company1:
{'1': 'november', '5': 'echo'}

desired:
        product     subproduct  company1    company2
0       a           1           november
1       a           2           bravo
2       a           3           charlie       
3       a           4                       
4       a           5           echo

and this dict for company2:
{'4': 'kilo', '2': 'foxtrot'}

desired:
        product     subproduct  company1    company2
0       a           1           november
1       a           2           bravo       foxtrot
2       a           3           charlie       
3       a           4                       kilo
4       a           5           echo

"""

感谢您花时间阅读,如果您想节省一两分钟重新创建数据帧结构和复制字典,这里有一个 pastebin:https://pastebin.com/raw/KkF77LCG

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    我的解决方案是基于使用update 来有效地更新 选择(例如 company1)。

    但是要使用update,您应该有一个 Series 的键等于特定 df 中的键(索引值),而所有字典的键都相等 到 subproduct 值,对于特定的 product

    所以成功的关键是“翻译”:

    • 来自 product / subproduct 值,
    • 索引值。

    要有效地做到这一点,首先要为 df 创建一个反向索引

    revInd = df.reset_index().set_index(['product', 'subproduct'])['index']
    

    这个想法是拥有 product / subproduct 对,您可以快速 获取df中相关行的索引(执行df.loc[...]要慢得多)。

    要检查它是如何工作的,运行 revInd[('a', '1')] 你会得到 0 - product == 'a'subproduct = '1' 的行索引 (我假设这两列都是 string 类型)。

    然后定义更新函数:

    def updCol(df, revInd, prodName, colName, dct):
        upd = pd.Series({ revInd[(prodName, k)]: v for k, v in dct.items() })
        df[colName].update(upd)
    

    参数:

    • df - 要更新的 DataFrame。
    • revInd - 反向索引。
    • prodName - 产品名称(选择标准的一部分)。
    • colName - 要更新的列名。
    • dct - 源字典。

    此函数根据字典理解生成 upd 系列, 从 product / subproduct 对执行转码 (字典键的子产品),到 df 中相关行的索引。 值没有改变。

    然后,根据upd,更新df中的相关列。 此更新发生在原地,因此无需返回任何结果。

    要检查我的解决方案,请创建“更新”字典:

    d1 = {'1': 'alpha', '2': 'bravo', '3': 'charlie'}
    d2 = {'1': 'november', '5': 'echo'}
    d3 = {'4': 'kilo', '2': 'foxtrot'}
    

    d1d2 用于 company1d3 用于 company2)。

    然后运行:

    updCol(df, revInd, 'a', 'company1', d1)
    updCol(df, revInd, 'a', 'company1', d2)
    updCol(df, revInd, 'a', 'company2', d3)
    

    如果你打印df,你会得到:

      product subproduct  company1 company2
    0       a          1  november         
    1       a          2     bravo  foxtrot
    2       a          3   charlie         
    3       a          4               kilo
    4       a          5      echo         
    

    应该如此。

    出于演示目的,在第一个和第二个之后运行 print(df) updCol 的调用。

    当然,我无法复制您应该完成的整个任务。 我只展示了如何在您的示例数据上使用上述函数。

    所以现在你的任务是将我的解决方案整合到你的代码中。

    【讨论】:

      猜你喜欢
      • 2016-02-10
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多