使用函数逐行计算pandas中旧列值的新列值

时间:2016-09-07 16:51:24

标签: python pandas dataframe calculated-columns

我知道关于这个话题有很多问题,但是在这种情况下似乎没有任何建议的答案可行,我认为这些答案是微不足道的,但现在已经杀了我2天了。

这是我第一次使用pandas处理来自眼动仪的导出文件。导出文件包含50个左右的列,其中2个包含瞳孔扩张测量,PupilLeft和PupilRight。我想创建一个新的列PupilAvg,它将两者平均化。当眼动仪无法读取一个或两个瞳孔时,它会记录-1。由于所需的逻辑很简单,但对于lambda来说似乎有点长,我写了一个函数来返回我的新列的值:

def getEyeAvg(left, right): 
    # calcs avg for Left and Right where one or both may be missing (= -1)
    if left == -1 and right == -1: return np.nan
    if left == -1: return right
    if right == -1: return left  
    return (left + right)/2.0 

以下是数据框的示例版本:

In[25]: dfd = pd.DataFrame.from_items([('PupilLeft', [3., -1., 4., -1]), ('PupilRight', [4., 4., -1., -1])])

In[26]: dfd
Out[26]: 
   PupilLeft  PupilRight
0        3.0         4.0
1       -1.0         4.0
2        4.0        -1.0
3       -1.0        -1.0

我想在PupilRight之后插入我的新列,所以我尝试命令:

In[27]: dfd.insert(2, 'PupilAvg', getEyeAvg(dfd.PupilLeft, dfd.PupilRight))

我对PupilAvg的期望是:

   PupilLeft  PupilRight  PupilAvg
0        3.0         4.0       3.5
1       -1.0         4.0       4.0
2        4.0        -1.0       4.0
3       -1.0        -1.0       NaN

当然这不起作用,我得到了

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我已经一遍又一遍地看到这个问题的变化,似乎每个答案都使用了一些不同的"技巧"鉴于我的相对初学者身份,这对我来说似乎难以理解。例如,我既不想要任何'任何'也不是所有的'左边的行== -1,我只想要当前行,但这似乎是pandas发现很难处理的请求。

如果有人可以为这个问题提供明确的一般解决方案,那将是非常有帮助的,这基本上归结为

  

"我想使用函数来逐行地使用来自其他列的值来计算新列的值,而不是一次全部。你知道,就像在Excel中一样。是否有一种简单,通用的方法可以做到这一点?"

对于像我这样试图从Excel解决方案过渡到python / pandas的人来说,这尤其困难,因为Excel自然是逐行的。您只需在第一行单元格中输入公式,然后将其一直复制到列中。显然,这种心态使我对大熊猫的准备不足。

1 个答案:

答案 0 :(得分:0)

在整个列上操作时,有一种简单的方法可以实现您的目标。

dfd.replace({-1:np.nan}, inplace=True)
dfd['PupilAvg'] = dfd.mean(axis=1)

如果由于某种原因需要保留原始的-1值,只需先复制它们然后继续。使用明确的纳米值,大熊猫中的所有东西都更容易。

您的原始代码失败,因为您将整个数据列传递给getEyeAvg。在你的例子中,它试图评估pd.DataFrame.from_items([('PupilLeft',[3。, - 。,4., - 1])== -1,而不是3. == 1.在整个列是pandas中的默认模式,所以它确实需要一种新的思维方式。没有任何一种最好的方法可以做到这一点,因为最有意义的方法来自Excel(直接通过行循环) index或use df.apply(lambda,axis = 1))比使用整列要慢得多。