【问题标题】:In pandas data frame how to apply own function multiple selective column and create a new column for that calculation在熊猫数据框中如何应用自己的函数多个选择列并为该计算创建一个新列
【发布时间】:2018-12-20 23:30:51
【问题描述】:

我的数据框(df)由 47 列和 30,000 行组成,列在下面

Index(['Unnamed: 0', 'CtpJobId', 'TransformJobStateId', 'LastError',
       'PriorityDate', 'QueuedTime', 'AccurateAsOf', 'SentToDevice',
       'StartedAtDevice', 'ProcessStart', 'LastProgressAt', 'ProcessEnd',
       'OutputFileDuration', 'Tags', 'SegmentId', 'VideoId',
       'ClipFirstFrameNumber', 'ClipLastFrameNumber', 'SourceId',
       'SourceNamedLocation', 'SourceDirectory', 'SourceFileSize',
       'srcMediaFormat', 'srcFrameRate', 'srcWidth', 'srcHeight', 'srcCodec',
       'srcDuration', 'TargetId', 'TargetNamedLocation', 'TargetDirectory',
       'TargetFilename', 'Description', 'TargetTags', 'tgtFrameRate',
       'tgtDropFrame', 'tgtWidth', 'tgtHeight', 'tgtCodec', 'DeviceType',
       'DeviceResourceId', 'AssignedDeviceId', 'DeviceName',
       'AssignedDeviceJobId', 'DeviceUri'],
      dtype='object')

我想为选择性列或该数据框应用一个函数来创建一个名为 df['seg_duration'] 的新列,所以我的函数如下

def seq_duration(df):

    if ClipFirstFrameNumber is not None and ClipLastFrameNumber is not None:
        fn = ClipLastFrameNumber -ClipFirstFrameNumber
        if FrameRate =='23.98' and DropFrame == 'False' :
            fps = 24 / 1.001
        elif FrameRate == '24' and DropFrame == 'False':
            fps = 24
        elif FrameRate == '25'and DropFrame == 'False':
            fps = 25
        elif  FrameRate == '29.97':
            fps = 30 / 1.001
        elif  FrameRate == '30' and DropFrame == 'False':
            fps = 30
        elif FrameRate == '59.94':
            fps = 60 / 1.001
        Duration = fn/fps

    elif srcDuration is not None:
         Duration = srcDuration
    else:
        None

该函数实际上有 3 种情况,在一种情况下有很多条件,所以首先我将 ClipLastFrameNumber 中的值减去 ClipFirstframeNumber 列并将其保存到 fn 变量。并应用其他逻辑,与 srcDuration 相同的是列及其值。比如下面

ClipLastFrameNumber ClipFirstFrameNumber    tgtDropFrame    tgtFrameRate
NaN                    NaN                    True          29.97
NaN                    NaN                    True          29.97
NaN                    NaN                    True          29.97
34354.0                28892.0                True          29.97

当我如下应用此功能时

df['seg_duration']=df.apply(seq_duration)

我收到错误NameError: ("name 'ClipFirstFrameNumber' is not defined", 'occurred at index Unnamed: 0')

这是为 pandas 编写函数的正确方法,或者我如何将这个函数用于该数据框并实现我的目标,即基于该函数创建一个新列 df['seg_dur']。提前致谢

【问题讨论】:

  • 这里发生了很多事情。seq_duration 需要为一行定义,而不是数据框;它还需要在最后返回一些东西。然后你想应用 axis = 1 传递给 apply 的函数。

标签: python python-3.x pandas data-science


【解决方案1】:

稍微修改你的函数:

def seq_duration(row):
    Duration = None
    if row.ClipFirstFrameNumber is not None and row.ClipLastFrameNumber is not None:
        fn = row.ClipLastFrameNumber -row.ClipFirstFrameNumber
        fps = 0
        if row.FrameRate =='23.98' and row.DropFrame == 'False' :
            fps = 24 / 1.001
        elif row.FrameRate == '24' and row.DropFrame == 'False':
            fps = 24
        elif row.FrameRate == '25'and row.DropFrame == 'False':
            fps = 25
        elif  row.FrameRate == '29.97':
            fps = 30 / 1.001
        elif  row.FrameRate == '30' and row.DropFrame == 'False':
            fps = 30
        elif row.FrameRate == '59.94':
            fps = 60 / 1.001
        if fps>0:
            Duration = fn/fps

    elif row.srcDuration is not None:
         Duration = row.srcDuration

    return Duration

那么你想要:

df['seg_duration']=df.apply(seq_duration,axis = 1)

【讨论】:

  • 非常感谢您的快速响应并更正了我的功能,我真的很感激,顺便说一句,我执行了 df['seg_duration']=df.apply(seq_duration,axis = 1),我会遇到错误,UnboundLocalError:(“分配前引用的局部变量'fps'”,'发生在索引0'),有什么想法吗?请您的帮助将挽救我的一天。
  • 这是一个没有定义fps但定义了fn的情况……你确定你的条件已经涵盖了所有的情况吗?
  • 是的,该函数应该只有三种情况,首先如果 row.ClipFirstFrameNumber 不是 None 并且 row.ClipLastFrameNumber 不是 None 然后从这个段落计算持续时间,elif row.srcDuration 不是 None 和 row .ClipFirstFrameNumber 为 None 且 row.ClipLastFrameNumber 为 None,如果这两种情况不成立且这三个都为 none,则持续时间为 none。
  • 现在它给出的错误是 UnboundLocalError: ("local variable 'Duration' referenced before assignment", 'occured at index 0')
  • 所以不是使用 is not None 你需要检查它们是否是 NaN
猜你喜欢
  • 2016-02-05
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-12
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
相关资源
最近更新 更多