Как получить доступ к значению серии Pandas в пользовательской функции

Я работаю над проектом по мониторингу моего 5-километрового времени для моих занятий бегом / бегом трусцой на основе их данных GPS. В настоящее время я изучаю свои данные в блокноте Jupyter и теперь понимаю, что мне нужно будет исключить некоторые действия.

Каждое действие представляет собой строку в фрейме данных. Хотя я хочу исключить некоторые строки, я не хочу удалять их из своего фрейма данных, поскольку я также буду использовать df для других вычислений.

Я добавил столбец в df вместе с пользовательской функцией для проверки причин недействительности строки. Возможно, запуск может быть исключен по нескольким причинам.

In []:
    # add invalidity reasons column & update logic
    df['invalidity_reasons'] = ''
    
    def maintain_invalidity_reasons(reason):
        """logic for maintaining ['invalidity reasons']"""
        reasons = []
        if invalidity_reasons == '':
            return list(reason)
        else:
            reasons = invalidity_reasons
            reasons.append(reason)
            return reasons

Я фильтрую до определенных строк в моем df и передаю их своей функции. В приведенном ниже примере возвращается набор из пяти строк из файла df. Ниже приведен пример использования функции в моем блокноте Jupyter.

In []:
    columns = ['distance','duration','notes']
    
    filt = (df['duration'] < pd.Timedelta('5 minutes'))
    df.loc[filt,columns].apply(maintain_invalidity_reasons('short_run'),axis=1)

Out []:
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-107-0bd06407ef08> in <module>
          2 
          3 filt = (df['duration'] < pd.Timedelta('5 minutes'))
    ----> 4 df.loc[filt,columns].apply(maintain_invalidity_reasons(reason='short_run'),axis=1)
    
    <ipython-input-106-60264b9c7b13> in maintain_invalidity_reasons(reason)
          5     """logic for maintaining ['invalidity reasons']"""
          6     reasons = []
    ----> 7     if invalidity_reasons == '':
          8         return list(reason)
          9     else:
    
    NameError: name 'invalidity_reasons' is not defined

Вот пример вывода моего фильтра, если я удалю вызов .apply() для моей функции

In []:
columns = ['distance','duration', 'notes','invalidity_reasons']

filt = (df['duration'] < pd.Timedelta('5 minutes'))
df.loc[filt,columns]

Out []:

Кажется, моя проблема заключается в том, что я не знаю, как указать, что я хочу ссылаться на скалярное значение в индексе/столбце 'invalidity_reasons' (не уверен в правильном термине) конкретной строки.

Я попытался настроить оператор IF с помощью приведенных ниже вариантов. Я также пытался применить функцию без/без аргумента оси. Я застрял, пожалуйста, помогите!

if 'invalidity_reasons' == '':
if s['invalidity_reasons'] == '':

Это кодовый суп. invalidity_reasons не определяется нигде до того, как используется, и list(reason) не делает того, что вы думаете.

cs95 24.12.2020 12:22

Я верю вам в вопросе list(reason). Как только я определяю, как правильно получить доступ к значению в ряду (т. е. в строке), я смогу продолжить устранение неполадок. invalidity_reasons — это столбец df, который я создаю перед тем, как начать какую-либо фильтрацию df. Это упоминается в первой строке первого блока кода в моем посте (прямо под комментарием). Для каждой строки инициал invalidity_reasons является пустой строкой, пока мне не нужно обновить ее с помощью моей функции.

Robert Brown 24.12.2020 13:59

Кроме того, я немного новичок в Python и Pandas, поэтому я с радостью приму любые отзывы о том, как улучшить мой кодовый суп.

Robert Brown 24.12.2020 14:01

Это if 'invalidity_reasons' == '' не имеет смысла (всегда будет False). И, как указал cs95, у вас нет переменной с именем invalidity_reasons. Тот факт, что в вашем фрейме есть столбец с таким именем, этого не делает.

Timus 24.12.2020 14:25
invalidity_reasons не должен быть переменной, а скорее индексом/меткой скалярного значения в каждой серии (то есть строке), которую я передаю своей функции. Чтобы прояснить свое намерение, я обновил свой пост примером вывода моего фильтра без вызова .apply(), чтобы показать, какие данные я хочу, чтобы моя функция воздействовала.
Robert Brown 24.12.2020 14:48

чтобы быть предельно ясным, я хочу сделать следующее: 1. передать строку или набор строк функции 2. для каждой строки я хочу, чтобы функция: 1. нашла значение определенного индекса/метки в строке 2. обновить указанное значение на основе его текущего значения (т. е. если пусто/пусто/нуль: выполните x; иначе: выполните y)

Robert Brown 24.12.2020 14:59

«invalidity_reasons не должен быть переменной» — но в вашем коде вы используете его так, как если бы это была переменная, и это источник вашей (текущей) ошибки: «NameError: имя 'invalidity_reasons' не определено».

Timus 24.12.2020 15:29

это мой вопрос, как я могу указать, что хочу ссылаться на скалярное значение ряда? Я пытался изменить то, как я ссылаюсь на него в заявлении IF, но безрезультатно. Обе альтернативы, которые я упоминаю в посте, также приводят к ошибке NameError.

Robert Brown 24.12.2020 15:34
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это в значительной степени удар в темноте, но я надеюсь, что это поможет. Далее я использую этот простой кадр в качестве примера (чтобы было с чем работать):

df = pd.DataFrame({'Col': range(5)})

Теперь, если вы определите

def maintain_invalidity_reasons(current_reasons, new_reason):
    if current_reasons == '':
        return [new_reason]
    if type(current_reasons) == list:
        return current_reasons + [new_reason]
    return [current_reasons] + [new_reason]

добавить еще один столбец invalidity_reasons в df

df['invalidity_reasons'] = ''

заполнить одну ячейку (для наглядности)

df.loc[0, 'invalidity_reasons'] = 'a reason'
   Col invalidity_reasons
0    0           a reason
1    1                   
2    2                   
3    3                   
4    4                   

построить фильтр

filt = (df.Col < 3)

а затем сделать

df.loc[filt, 'invalidity_reasons'] = (df.loc[filt, 'invalidity_reasons']
                                        .apply(maintain_invalidity_reasons,
                                               args=('another reason',)))

ты получишь

   Col          invalidity_reasons
0    0  [a reason, another reason]
1    1            [another reason]
2    2            [another reason]
3    3                            
4    4                            

Это как-то похоже на то, что вы ищете?

да, это то, что мне было нужно. Я думаю, что самая большая часть моей проблемы заключалась в том, что у меня не было аргумента в моей функции для представления самой серии (current_reasons в вашей функции). Спасибо за ваше терпение и помощь!

Robert Brown 24.12.2020 16:21

Другие вопросы по теме