Итерация по словарю вытягивает неправильное значение для искомого ключа - PullRequest
0 голосов
/ 30 марта 2019

Я использовал Pandas для чтения листа Excel, в котором используются два столбца, для создания словаря значений и ключей. При запуске код будет искать ключ и выводить его значение. Пример: WSO-Exchange будет равен 52206.

enter image description here

Хотя, когда я ищу значение 59904-FX, он возвращает 35444, когда мне нужно вернуть 22035; Эта проблема возникает только тогда, когда ключ также является значением позже. Любые идеи о том, как я могу исправить эту ошибку? Я прикреплю свой код ниже, спасибо!

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

df ["AccountID"] [i] читает другой лист Excel, чтобы найти, находится ли эта ячейка в ключах словаря, и если это так, то изменить ее на ее значение.

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

Ответы [ 3 ]

0 голосов
/ 30 марта 2019

Проверка индекса на наличие дубликатов в файле Excel

Скорее всего, проблема в том, что вы перебираете неуникальный индекс DataFrame Mapdf. Убедитесь, что первый столбец в файле Excel, который вы используете для построения Mapdf, уникален для каждой строки.

Не перебирать строки данных

Однако, вместо того, чтобы пытаться перебирать строки в DataFrame (что почти всегда неправильно), вы можете построить словарь с вызовом dict конструктора , передав ему итерация пар (ключ, значение):

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

Рассмотрим слияние, а не зацикливание

Еще лучше то, что вы делаете, кажется идеальным кандидатом на DataFrame.merge.
Похоже, что вы хотите перезаписать значения AccountId в df значениями Upload Code в Mapdf, если AccountId имеет совпадение в General Code в Mapdf. Это полный рот, но давайте разберемся с этим.

Сначала добавьте Mapdf к df по соответствующим столбцам (df["AccountId"] до Mapdf["General Code"]):

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")

Поскольку это левое соединение , строки в merged, где столбец AccountId не имеет совпадения в Mapdf["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)
0 голосов
/ 03 апреля 2019

РЕДАКТИРОВАТЬ: Оказывается, мне не нужно было делать вложенный цикл. Решением было перейти от цикла for к условию if.

for i in df.index:
    if str(df['AccountId'][i]) in str(MapDatabase.items()):
        df.at[i, 'AccountId'] = MapDatabase[df['AccountId'][i]]
0 голосов
/ 30 марта 2019

Я бы просто использовал библиотеку 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}
...