вызовите ошибку ключа(ключ) из ошибки Ошибка ключа: ‘right_only’ / ‘оба’

#python #pandas #merge #keyerror

Вопрос:

Я пытаюсь разработать python comparer. У меня проблема с моей переменной с именем: compare_type которую я хочу установить либо в l-left join / r - right join / b - inner join (both)

если я настрою compare_type = 'l'; все работает нормально

Тем не менее, когда я делаю либо compare_type = 'r'; или compare_type = 'b'; десять, я получаю следующие ошибки:

    raise KeyError(key) from err
KeyError: 'both'
 

или

     raise KeyError(key) from err
KeyError: 'right_only'
 

Что я делаю не так?

Полный код:

 import pandas as pd

col_to_compare = 0;
compare_type = 'r';     #l-left join / r - right join / b - inner join (both)

file1_df = pd.read_csv('filename1.csv', usecols=[col_to_compare], names=[col_to_compare])
file2_df = pd.read_csv('filename2.csv', usecols=[col_to_compare], names=[col_to_compare])

file1_df[col_to_compare] = file1_df[col_to_compare].str.upper()
file2_df[col_to_compare] = file2_df[col_to_compare].str.upper()

comparison_result = pd.merge(file1_df, file2_df, on=col_to_compare,
                             how='left' if (compare_type == 'l') else 'right' if (compare_type == 'r') else 'inner',
                             indicator=True)

comparison_result = comparison_result.loc[comparison_result['_merge'] == 'left_only' if (compare_type == 'l') else 'right_only' if (compare_type == 'r') else 'both']

print(comparison_result)
comparison_result.to_csv('result.csv')
 

Полная обратная связь:

 C:UsersjohnPycharmProjectsL1venvScriptspython.exe C:/Users/john/PycharmProjects/L1/CsvComparer/csv_comparer.py
Traceback (most recent call last):
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoreindexesbase.py", line 3361, in get_loc
    return self._engine.get_loc(casted_key)
  File "pandas_libsindex.pyx", line 76, in pandas._libs.index.IndexEngine.get_loc
  File "pandas_libsindex_class_helper.pxi", line 105, in pandas._libs.index.Int64Engine._check_type
  File "pandas_libsindex_class_helper.pxi", line 105, in pandas._libs.index.Int64Engine._check_type
KeyError: 'right_only'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:/Users/john/PycharmProjects/L1/CsvComparer/csv_comparer.py", line 29, in <module>
    comparison_result = comparison_result.loc[comparison_result['_merge'] == 'left_only' if (compare_type == 'l') else 'right_only' if (compare_type == 'r') else 'both']
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoreindexing.py", line 931, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoreindexing.py", line 1164, in _getitem_axis
    return self._get_label(key, axis=axis)
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoreindexing.py", line 1113, in _get_label
    return self.obj.xs(label, axis=axis)
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoregeneric.py", line 3776, in xs
    loc = index.get_loc(key)
  File "C:UsersjohnPycharmProjectsL1venvlibsite-packagespandascoreindexesbase.py", line 3363, in get_loc
    raise KeyError(key) from err
KeyError: 'right_only'

Process finished with exit code 1
 

Комментарии:

1. можете ли вы предоставить полную обратную связь? обратные трассировки действительно важны для отладки.

2. Добавил @MichaelDelgado.

Ответ №1:

У вас возникли проблемы со следующей строкой :

 comparison_result['_merge'] == 'left_only' if (compare_type == 'l') else 'right_only' if (compare_type == 'r') else 'both'
 

Мой Рабочий Код:

 import pandas as pd

col_to_compare = '0';
compare_type = 'r';     #l-left join / r - right join / b - inner join (both)

# file1_df = pd.read_csv('filename1.csv', usecols=[col_to_compare], names=[col_to_compare])
# file2_df = pd.read_csv('filename2.csv', usecols=[col_to_compare], names=[col_to_compare])
file1_df = pd.DataFrame(
    {
        "0": ["K0", "K1", "K2", "K3"],
        "1": ["A0", "A1", "A2", "A3"],
        "2": ["B0", "B1", "B2", "B3"],
    }
)

file2_df = pd.DataFrame(
    {
        "0": ["K1", "K2", "K3", "K4"],
        "3": ["C0", "C1", "C2", "C3"],
        "4": ["D0", "D1", "D2", "D3"],
    }
)


file1_df[col_to_compare] = file1_df[col_to_compare].str.upper()
file2_df[col_to_compare] = file2_df[col_to_compare].str.upper()

comparison_result = pd.merge(file1_df, file2_df, on = col_to_compare, how = ('left' if (compare_type == 'l') else 'right' if (compare_type == 'r') else 'inner'), indicator = True)

print(f'{comparison_result}n')

comparison_result = comparison_result.loc[comparison_result['_merge'] == ('left_only' if (compare_type == 'l') else ('right_only' if (compare_type == 'r') else 'both'))]

print(f'{comparison_result}')
# comparison_result.to_csv('result.csv')

 

Вывод для compare_type = 'r' :

правильно только

Вывод для compare_type = 'l' :

только слева

Вывод для compare_type = 'b' :

оба

Примечания:

Я внес некоторые незначительные изменения для отладки проблемы, чтобы вы могли избежать их.
Избегайте рендеринга строк условий во фрейме данных

Комментарии:

1. вместо того, чтобы иметь отдельную строку для row_value, как правильно разместить ее непосредственно в целевой строке? Попытался просто взять это, но с ошибкой. Просто хочу, чтобы он был встроен без дополнительной переменной row_value.

2. Я не уверен, но я думаю comparison_result.loc[] , что не поддерживает условное значение. Я могу ошибаться, но, похоже, в этом и проблема.

3. Это определенно неправда. вопрос в порядке выполнения операций. Если вы хотите, чтобы это было в одной строке, используйте круглые скобки, чтобы заставить оператор равенства работать с результатом условных операторов, например comparison_result['_merge'] == ('left_only' if (compare_type == 'l') else ('right_only' if (compare_type == 'r') else 'both'))

4. Спасибо. Я не знал об этом. 🙂

Ответ №2:

это просто проблема в вашем цепном неравенстве и операторах if.

 comparison_result['_merge'] == 'left_only' if (compare_type == 'l') else 'right_only' if (compare_type == 'r') else 'both'
 

оценивает в следующем порядке:

 (
    (comparison_result['_merge'] == 'left_only')
    if (compare_type == 'l')
    else ('right_only' if (compare_type == 'r') else 'both')
)
 

Когда compare_type есть 'r' , оператор if приводит ко всему условию, приводящему к:

 comparison_result.loc['right_only']
 

Вот почему вы получаете эту ошибку ключа.

Используйте круглые скобки, чтобы уточнить порядок операций, которые вы хотите, или, еще лучше, определите переменную, которая будет более читаемой. В этом случае:

 if (compare_type == 'l'):
    target_val = 'left_only'
elif (compare_type == 'r'):
    target_val = 'right_only'
else:
    target_val = 'both'

comparison_result = comparison_result.loc[comparison_result['_merge'] == target_val]