我知道关于这个话题有很多问题,但是在这种情况下似乎没有任何建议的答案可行,我认为这些答案是微不足道的,但现在已经杀了我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自然是逐行的。您只需在第一行单元格中输入公式,然后将其一直复制到列中。显然,这种心态使我对大熊猫的准备不足。
答案 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))比使用整列要慢得多。