#python #pandas #jupyter
#python #pandas #jupyter
Вопрос:
Я работаю над проектом по мониторингу моего времени 5k для моих занятий бегом / бегом трусцой на основе их данных GPS. В настоящее время я изучаю свои данные в записной книжке Jupyter и теперь понимаю, что мне нужно будет исключить некоторые действия.
Каждое действие представляет собой строку в фрейме данных. Хотя я хочу исключить некоторые строки, я не хочу удалять их из своего фрейма данных, поскольку я также буду использовать df для других вычислений.
Я добавил столбец в df вместе с пользовательской функцией для проверки причин недействительности строки. Возможно, что запуск может быть исключен по нескольким причинам.
In []:
# add invalidity reasons column amp; 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
оператор с помощью приведенных ниже вариантов. Я также пытался применить функцию с / без аргумента axis. Я застрял, пожалуйста, помогите!
if 'invalidity_reasons' == '':
if s['invalidity_reasons'] == '':
Комментарии:
1. Это суп с кодом.
invalidity_reasons
нигде не определяется до его использования иlist(reason)
не выполняет то, что вы думаете.2. Я верю вам в отношении
list(reason)
проблемы. Как только я определю, как правильно получить доступ к значению в серии (т. Е. К строке), я смогу устранить его в дальнейшем.invalidity_reasons
это столбец df, который я создаю перед началом любой фильтрации df. Это упоминается в первой строке первого блока кода в моем сообщении (прямо под комментарием). Для каждой строки начальная частьinvalidity_reasons
является пустой строкой, пока мне не понадобится обновить ее с помощью моей функции.3. Кроме того, я немного новичок в Python и Pandas, поэтому я с радостью приму любые отзывы о том, как улучшить мой code soup.
4. Это
if 'invalidity_reasons' == ''
не имеет смысла (всегда будетFalse
). И, как указал cs95, у вас нет имени переменнойinvalidity_reasons
. Тот факт, что в вашем фрейме есть столбец с таким именем, этого не делает.5.
invalidity_reasons
предполагается, что это не переменная, а скорее индекс / метка скалярного значения в каждой серии (т.Е. Строке), которую я передаю своей функции. Чтобы прояснить свое намерение, я обновил свой пост примером вывода моего фильтра без вызова .apply(), чтобы показать, на какие данные я хочу, чтобы моя функция действовала.
Ответ №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
Это как-то похоже на то, что вы ищете?
Комментарии:
1. да, это то, что мне было нужно. Я думаю, что большая часть моей проблемы заключалась в том, что у меня не было аргумента в моей функции для представления самой серии (
current_reasons
в вашей функции). Спасибо за ваше терпение и помощь!