【问题标题】:Iteration through dictionary pulling the wrong value for searched key通过字典迭代为搜索的键提取错误的值
【发布时间】:2019-03-30 01:19:40
【问题描述】:

我使用 Pandas 读取了一个 excel 表,其中有两列用于创建键值字典。运行时,代码将搜索一个键,并产生它的值。例如:WSO-Exchange 将等于 52206。

虽然,当我搜索 59904-FX 的值时,当我需要它返回 22035 时它返回 35444;仅当键稍后也是值时才会引发此问题。关于如何解决此错误的任何想法?我会在下面附上我的代码,谢谢!

MapDatabase = {}
    for i in Mapdf.index:
        MapDatabase[Mapdf['General Code'][i]] = Mapdf['Upload Code'][i]

df["AccountID"][i] 正在读取另一个 Excel 表,以搜索该单元格是否在字典的键中,如果是,则将其更改为它的值。 p>

for i in df.index:
    for key, value in MapDatabase.items():
        if str(df['AccountId'][i]) == str(key):
            df['AccountId'][i] = value

【问题讨论】:

  • 您也应该提供数据样本。
  • DataFrame 的索引是多少?当你读入 Excel 文件时,你告诉 pandas 用什么做索引?
  • @PaSTE 索引是在 MapDatabase 字典中搜索的值。
  • 对不起,我的意思是您在生成Mapdf的Excel文件中读取的代码是什么,“通用代码”和“上传代码”左侧的列是什么?

标签: python python-3.x loops for-loop iteration


【解决方案1】:

我会使用 xlrd 库来做到这一点:

from xlrd import open_workbook

workbook = open_workbook("data.xlsx")
sheet = workbook.sheet_by_index(0)

data = {sheet.cell(row, 0).value: sheet.cell(row, 1).value for row in range(sheet.nrows)}

print(data)

它给出了以下字典:

{'General Code': 'Upload Code', '59904-FX': 22035.0, 'WSO-Exchange': 52206.0, 56476.0: 99875.0, 22035.0: 35444.0}

【讨论】:

    【解决方案2】:

    检查 Excel 文件中的重复索引

    问题很可能是您正在迭代 DataFrame Mapdf 的非唯一索引。检查您用于构建 Mapdf 的 Excel 文件中的第一列是否每行都是唯一的。

    不要迭代 DataFrame 行

    但是,您可以通过调用dict constructor 来构建字典,而不是尝试在 DataFrame 上逐行迭代(这几乎总是错误的做法),并将其传递给 (key,值)对:

    MapDatabase = dict(zip(Mapdf["General Code"], Mapdf["Upload Code"]))
    

    考虑合并而不是循环

    更好的是,您所做的似乎是DataFrame.merge 的理想人选。
    看起来你想要做的是用Mapdf 中的Upload Code 的值覆盖df 中的AccountId 的值,如果AccountIdGeneral Code 中的Mapdf 匹配。这是一口,但让我们分解一下。

    首先,通过匹配列(df["AccountId"]Mapdf["General Code"])将 Mapdf 合并到 df

    columns = ["General Code", "Upload Code"]  # only because it looks like there are more columns you don't care about
    merged = df.merge(Mapdf[columns], how="left", left_on = "AccountId", right_on="General Code")
    

    因为这是一个left join,所以merged 中的行AccountIdMapdf["General Code"] 中没有匹配项将缺少Upload Code 的值。复制非缺失值以覆盖AccountId

    matched = merged["Upload Code"].notnull()
    merged.loc[matched, "AccountId"] = merged.loc[matched, "Upload Code"]
    

    如果您愿意,可以删除多余的列:

    merged.drop(["Upload Code", "General Code"], axis="columns", inplace=True)
    

    【讨论】:

    • 感谢@PaSTE 的提示,尽管这并不能解决问题。我尝试删除重复项,尝试 dict zip 和列合并,但仍然没有。我假设它与这段代码有关:'for i in df.index: for key, value in MapDatabase.items(): if str(df['AccountId'][i]) == str (键):df['AccountId'][i] = value'
    【解决方案3】:

    编辑:原来我不需要做一个嵌套的 for 循环。解决方案是从 for 循环转到 if 语句。

    for i in df.index:
        if str(df['AccountId'][i]) in str(MapDatabase.items()):
            df.at[i, 'AccountId'] = MapDatabase[df['AccountId'][i]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 2021-04-05
      • 2023-02-02
      • 2013-04-26
      • 1970-01-01
      相关资源
      最近更新 更多