Python内部函数无法访问外部函数局部变量df的问题咨询
问题原因
你碰到的"Unresolved reference 'df'"错误,核心原因是子函数accumulate_df的else分支里写了df = df.append(...)——Python会把这种赋值操作认定为你要在子函数内创建局部变量df,因此整个子函数里的df都会被当作局部变量处理。但if分支里先访问了df,此时局部的df还未定义,就触发了未解析引用的错误。
解决方案
有两种直接的修复方式:
方式一:用nonlocal声明变量
在子函数开头加上nonlocal df,明确告诉Python:这个df不是子函数的局部变量,而是外层函数func1中的变量,这样赋值操作就会直接修改外层的df:
import pandas as pd import numpy as np def func1(): # Initialization for accumulated df df = pd.DataFrame(columns=['col1', 'col2', 'col3', 'col4']) df['col1'] = df['col1'].astype('string') df['col2'] = df['col2'].astype(np.float32) df['col3'] = df['col3'].astype(np.int32) df['col4'] = df['col4'].astype(np.float64) def accumulate_df(result_tuple): nonlocal df # 声明df来自外层函数 col1_value = result_tuple[0] col2_value = result_tuple[1] col3_value = result_tuple[2] col4_value = result_tuple[3] if df[(df['col1'] == col1_value) & (df['col2'] == col2_value)].values.any(): # Update Accumulate df.loc[(df['col1'] == col1_value) & (df['col2'] == col2_value), 'col3'] += col3_value df.loc[(df['col1'] == col1_value) & (df['col2'] == col2_value), 'col4'] += col4_value else: df = df.append({'col1': col1_value, 'col2': col2_value, 'col3': col3_value, 'col4': col4_value}, ignore_index=True)
方式二:避免重新赋值df
df.append()会返回新的DataFrame,你可以直接修改原df的行,不用重新赋值。比如用df.loc[len(df)] = ...添加新行,这样子函数里不会出现对df的赋值操作,自然会引用外层的df:
import pandas as pd import numpy as np def func1(): # Initialization for accumulated df df = pd.DataFrame(columns=['col1', 'col2', 'col3', 'col4']) df['col1'] = df['col1'].astype('string') df['col2'] = df['col2'].astype(np.float32) df['col3'] = df['col3'].astype(np.int32) df['col4'] = df['col4'].astype(np.float64) def accumulate_df(result_tuple): col1_value = result_tuple[0] col2_value = result_tuple[1] col3_value = result_tuple[2] col4_value = result_tuple[3] mask = (df['col1'] == col1_value) & (df['col2'] == col2_value) if mask.any(): # Update Accumulate df.loc[mask, 'col3'] += col3_value df.loc[mask, 'col4'] += col4_value else: # 直接给原df添加行,不重新赋值df df.loc[len(df)] = { 'col1': col1_value, 'col2': col2_value, 'col3': col3_value, 'col4': col4_value }
多处理器场景注意点
你提到要用多处理器累加结果,需要注意:多进程模式下,每个子进程会复制一份df的内存空间,进程间的变量修改不会共享。因此最后需要把各个进程的结果df收集起来,再合并成最终的df,而非直接在子进程里修改同一个df。
内容的提问来源于stack exchange,提问作者burcak
相关产品推荐
相关产品推荐

