В Python3, вы можете использовать ключевое слово нелокального:
def outer_method():
... do outer scope stuff here
df = pd.DataFrame(columns=['A','B','C','D'])
def recursive_method(arg):
nonlocal df
... do local stuff here
# func returns a data frame to be appended to empty data frame
results_df = func(args)
df = df.append(results_df, ignore_index=True)
return results
return df
Но обратите внимание, что вызов df.append
возвращает новый DataFrame каждый раз, и, следовательно, требует копирования все старые данные в новую DataFrame. Если вы делаете это внутри цикла N раз, вы в итоге получаете порядка 1 + 2 + 3 + ... + N = O (N^2) копии - очень плохо для производительности.
Если вам не нужно df
внутри recursive_method
для любых целей, кроме добавляющих, то лучше добавить в список, а затем построить DataFrame (по телефону pd.concat
раз) после того, как recursive_method
делается :
df = pd.DataFrame(columns=['A','B','C','D'])
data = [df]
def recursive_method(arg, data):
... do stuff here
# func returns a data frame to be appended to empty data frame
results_df = func(args)
data.append(df_join_out)
return results
recursive_method(arg, data)
df = pd.concat(data, ignore_index=True)
Это лучшее решение, если все, что вам нужно сделать, это собрать данные внутри recursive_method
и может ждать, чтобы построить новый df
после recursive_method
сделан.
В python2, если вы должны использовать df
внутри recursive_method
, то вы могли бы пройти df
в качестве аргумента recursive_method
и вернуть df
слишком:
df = pd.DataFrame(columns=['A','B','C','D'])
def recursive_method(arg, df):
... do stuff here
results, df = recursive_method(arg, df)
# func returns a data frame to be appended to empty data frame
results_df = func(args)
df = df.append(results_df, ignore_index=True)
return results, df
results, df = recursive_method(arg, df)
, но быть в курсе, что вы будете заплатив большую цену за копирование 0 (N^2) , упомянутое выше.
Почему DataFrames
не может
не должен быть добавлен в месте:
, лежащие в основе данные в DataFrame хранится в NumPy массивов. Данные в массиве NumPy поступают из непрерывного блока памяти. Иногда нет места , чтобы изменить размер массивов NumPy на более крупный смежный блок памяти , даже если память доступна. Представьте, что массив находится между иными структурами данных. В этом случае для изменения размера массива новый более крупный блок памяти должен быть выделен где-то еще, и все данные из исходного массива должны быть скопированы в новый блок. В целом, это не может быть сделано на месте.
DataFrames
У меня есть частный метод, _update_inplace
, который может быть используется для перенаправления базовых данных DataFrame на новые данные. Это всего лишь pseudo-inplace operation, так как новые данные (считайте массивы NumPy) должны быть , выделенные (со всем сопровождающим копированием). Таким образом, используя _update_inplace
, два удара против него: он использует частный метод, который (теоретически) может быть не вокруг в будущих версиях Панд, и он несет штраф за копирование O (N^2).
In [231]: df = pd.DataFrame([[0,1,2]])
In [232]: df
Out[232]:
0 1 2
0 0 1 2
In [233]: df._update_inplace(df.append([[3,4,5]]))
In [234]: df
Out[234]:
0 1 2
0 0 1 2
0 3 4 5
Извините, вы говорите, что 'df = df.append (df_join_out, ignore_index = True)' не работает? – EdChum
'df' с правой стороны затем передается как нерешенная ссылка. –