bug记录
df_example = fun_merge()
第一遍运行 正常
第二遍运行 报错
KeyError: "['unique_serial_number'] not in index"
但是 如果每次都先重新运行函数 再运行实例 就不会报错
原因
fun_merge()默认参数中df_left被覆盖
第一次运行时生成了df_left
第二次运行时优先使用已生成的df_left
解决办法1
df_test = pd.DataFrame({'OldCol': range(3)})
fun_merge(df_left=df_test)
解决办法2
避免重名
import pandas as pd
def fun_merge(
df_left=pd.DataFrame({'OldCol': range(3)}),
df_right=pd.DataFrame({'NewCol': range(2)}),
str_NewCol='NewCol',
str_LeftOn='OldCol',
str_RightOn='NewCol',
str_how='left',
tuple_suffix=('', '_y'),
str_UniqueSerialNumber='unique_serial_number',
bool_cover=False,
str_OldCol='OldCol',
bool_create=False,
str_CreateCol='CreateCol'
):
# 生成列名
list_columns = df_left.columns.tolist()
if str_NewCol in list_columns:
str_NewCol += tuple_suffix[-1]
list_columns.append(str_NewCol)
else:
list_columns.append(str_NewCol)
# 匹配df_right的str_NewCol列
# 生成唯一序列号列_左匹配_删除重复行
# 保留df_left和str_NewCol列_(也删除了唯一序列号列)
df_result = df_left.copy()
df_result[str_UniqueSerialNumber] = range(df_result.shape[0])
df_result = df_result.merge(
right=df_right,
left_on=str_LeftOn,
right_on=str_RightOn,
how=str_how,
suffixes=tuple_suffix
).drop_duplicates(
str_UniqueSerialNumber, keep='first'
)
df_result = df_result.loc[
:, list_columns
]
# 如果匹配结果覆盖原有列
if bool_cover:
df_result[str_OldCol] = df_result[str_NewCol]
df_result.drop(columns=str_NewCol, inplace=True)
# 如果匹配结果重命名为新列
elif bool_create:
df_result.rename(columns={str_NewCol: str_CreateCol}, inplace=True)
return df_result
原函数
import pandas as pd
def fun_merge(
self,
df_left=pd.DataFrame({'OldCol': range(3)}),
df_right=pd.DataFrame({'NewCol': range(2)}),
str_NewCol='NewCol',
str_LeftOn='OldCol',
str_RightOn='NewCol',
str_how='left',
tuple_suffix=('', '_y'),
str_UniqueSerialNumber='unique_serial_number',
bool_cover=False,
str_OldCol='OldCol',
bool_create=False,
str_CreateCol='CreateCol'
):
# 生成列名
list_columns = df_left.columns.tolist()
if str_NewCol in list_columns:
str_NewCol += tuple_suffix[-1]
list_columns.append(str_NewCol)
else:
list_columns.append(str_NewCol)
# 匹配df_right的str_NewCol列
# 生成唯一序列号列_左匹配_删除重复行_删除唯一序列号列
# 保留df_left和str_NewCol列
df_left[str_UniqueSerialNumber] = range(df_left.shape[0])
df_left = df_left.merge(
right=df_right,
left_on=str_LeftOn,
right_on=str_RightOn,
how=str_how,
suffixes=tuple_suffix
).drop_duplicates(
str_UniqueSerialNumber, keep='first'
).drop(
columns=str_UniqueSerialNumber
)
df_left = df_left.loc[
:, list_columns
]
# 如果匹配结果覆盖原有列
if bool_cover:
df_left[str_OldCol] = df_left[str_NewCol]
df_left.drop(columns=str_NewCol, inplace=True)
# 如果匹配结果重命名为新列
elif bool_create:
df_left.rename(columns={str_NewCol: str_CreateCol}, inplace=True)
return df_left