【问题标题】:raise KeyError(key) from err KeyError: 'right_only' / 'both'从 err KeyError 引发 KeyError(key): 'right_only' / 'both'
【发布时间】:2021-08-31 21:22:25
【问题描述】:

我尝试开发 python 比较器。我的变量名为: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:\Users\john\PycharmProjects\L1\venv\Scripts\python.exe C:/Users/john/PycharmProjects/L1/CsvComparer/csv_comparer.py
Traceback (most recent call last):
  File "C:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\indexes\base.py", line 3361, in get_loc
    return self._engine.get_loc(casted_key)
  File "pandas\_libs\index.pyx", line 76, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index_class_helper.pxi", line 105, in pandas._libs.index.Int64Engine._check_type
  File "pandas\_libs\index_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:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\indexing.py", line 931, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "C:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\indexing.py", line 1164, in _getitem_axis
    return self._get_label(key, axis=axis)
  File "C:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\indexing.py", line 1113, in _get_label
    return self.obj.xs(label, axis=axis)
  File "C:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\generic.py", line 3776, in xs
    loc = index.get_loc(key)
  File "C:\Users\john\PycharmProjects\L1\venv\lib\site-packages\pandas\core\indexes\base.py", line 3363, in get_loc
    raise KeyError(key) from err
KeyError: 'right_only'

Process finished with exit code 1

【问题讨论】:

标签: python pandas merge keyerror


【解决方案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' 的输出:

注意事项:

我做了一些小改动来调试问题,这样你就可以避免这些。
避免在 DataFrame 中呈现条件字符串

【讨论】:

  • 而不是为row_value设置单独的行,如何正确地将其直接放置在目标行中?试图采取这个但有错误。只想让它内联而不需要额外的 row_value 变量。
  • 我不确定,但我认为comparison_result.loc[] 不支持条件值。我可能错了,但似乎这就是问题所在。
  • 这绝对不是真的。问题是操作顺序。如果您希望它在一行中,请使用括号强制相等运算符处理条件语句的结果,例如comparison_result['_merge'] == ('left_only' if (compare_type == 'l') else ('right_only' if (compare_type == 'r') else 'both'))
  • 谢谢。我没有意识到这一点。 :)
【解决方案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']

这就是您收到 KeyError 的原因。

使用括号来阐明您想要的操作顺序,或者更好的是,定义一个更易读的变量。在这种情况下:

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]

【讨论】:

    猜你喜欢
    • 2021-01-06
    • 2021-11-10
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 2021-05-29
    • 1970-01-01
    相关资源
    最近更新 更多