【问题标题】:How to access Pandas series value in a custom function如何在自定义函数中访问 Pandas 系列值
【发布时间】:2020-12-24 11:17:33
【问题描述】:

我正在开展一个项目,根据他们的 GPS 数据监控我的跑步/慢跑活动的 5k 时间。我目前正在 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 notebook 中使用该函数的示例。

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) 不会做你认为它做的事情。
  • 我相信你关于list(reason) 的问题。一旦我确定如何正确访问系列中的值(即行),我应该能够进一步排除故障。 invalidity_reasons 是我在开始过滤 df 之前创建的 df 列。在我的帖子的第一个代码块的第一行中提到了它(就在评论下方)。对于每一行,invalidity_reasons 的首字母是一个空字符串,直到我需要用我的函数更新它。
  • 另外,我对 Python 和 Pandas 有点陌生,所以我很乐意接受任何有关如何改进我的代码汤的反馈。
  • 这个if 'invalidity_reasons' == '' 没有意义(永远是False)。而且,正如 cs95 所指出的,您没有名为invalidity_reasons变量。您的框架有一个具有该名称的列这一事实不会发生这种情况。
  • invalidity_reasons 不应该是变量,而是我传递给函数的每个系列(即行)中标量值的索引/标签。为了阐明我的意图,我用我的过滤器输出示例更新了我的帖子,没有调用 .apply() 来显示我希望我的函数对哪些数据进行操作。

标签: python pandas jupyter


【解决方案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)。感谢您的耐心和帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多