2014-07-15 8 views
0

Я хочу написать функцию, которая принимает в качестве входных данных кадр данных Pandas и возвращает только строки со средним значением, превышающим определенный порог. Функция работает, но имеет побочный эффект изменения ввода, который я не хочу делать.Функции кадров данных pandas и побочных эффектов

def Remove_Low_Average(df, sample_names, average_threshold=30): 
    data_frame = df 
    data_frame['Mean'] = np.mean(data_frame[sample_names], axis=1) 
    data_frame = data_frame[data_frame.Mean > 30] 
    return data_frame.reset_index(drop=True) 

Пример:

In [7]: junk_data = DataFrame(np.random.randn(5,5), columns=['a', 'b', 'c', 'd', 'e']) 
In [8]: Remove_Low_Average(junk_data, ['a', 'b', 'c'], average_threshold=0) 
In [9]: junk_data.columns 
Out[9]: Index([u'a', u'b', u'c', u'd', u'e', u'Mean'], dtype='object') 

Так junk_data теперь имеет «Среднее» в своих колонках, хотя это никогда не присвоенных в функции. Я понимаю, что могу сделать это проще, но это иллюстрирует проблему, с которой я регулярно сталкиваюсь, я не могу понять, почему. Я полагаю, что это должно быть хорошо известно, но я не знаю, как добиться этого побочного эффекта.

EDIT: Приведенная ниже ссылка EdChum отвечает на вопрос.

+0

Что вы ожидаете этой линии сделать: 'data_frame [«Mean»] = np.mean (data_frame [образец _names], axis = 1) '? если вы просто хотите вычислить локальную переменную, то почему бы не просто «mean = np.mean (data_frame [sample_names], axis = 1)»? – EdChum

+0

@EdChum Это минимальный пример, который иллюстрирует проблему, с которой я сталкиваюсь с большей функцией. Я * ожидаю *, потому что я обращаюсь к переменной data_frame (которая не передается функции), что он оставит df (который) неизменным. Ясно, что это не так. Мне интересно, почему, что это называется, и как обойти это, и где в документах Pandas я мог бы больше узнать об этом. – MTrenfield

+0

Ну, вам нужно понять, что вы, скорее всего, рассматриваете данные, поэтому любая форма назначения влияет на исходный фреймворк данных, в вашем примере кажется совершенно ненужным создание нового столбца для этого вычисления. – EdChum

ответ

0

@EdChum ответил на это в комментариях:

см this page так в основном, если вы хотите, чтобы избежать изменения оригинала выполните глубокую копию по телефону .copy()

0

Вы надеваете» т нужно скопировать старый dataframe, просто не назначить новый столбец :)

def remove_low_average(df, sample_names, average_threshold=30): 
    mean = df[sample_names].mean(axis=1) 
    return df.ix[mean > average_threshold] 

# then use it as: 
df = remove_low_average(df, ['a', 'b']) 
Смежные вопросы