计算Pandas中的条件均值

时间:2015-08-29 02:20:23

标签: python-3.x numpy pandas

我有一个Pandas数据框如下:

import pandas as pd
data = pd.DataFrame([[1, 1, 100], [1, 2, 101], [1, 3, 102], 
                     [2, 1, 103], [2, 2, 104], [2, 3, 105], 
                     [3, 1, 106] ,[3, 2, 107], [3, 3, 108]],
                    columns=['row', 'column', 'cell value'])

每行数据代表一个单元格的值和位置(按“行”和“列”)。我希望做的是计算每个细胞的相邻细胞的平均细胞值。例如,对于单元格(行== 2列== 2),我需要从以下计算的平均单元格值:

  • 单元格值(行== 1,列== 2)
  • 单元格值(行== 3,列== 2)
  • 单元格值(行== 2,列== 1)
  • 单元格值(行== 2,列== 3)

我需要将此计算应用于每个单元格。

我有以下定义的功能:

此函数提取特定单元格的单元格值:

def val(r,c):
    return float(data['cell value'][(data['row'] == r) & (data['column'] == c)])

此函数提取相邻的单元格值:

def adjval(r,c): 
    adj = []
    if r != data['row'].max(): 
        adj.append(thick(r + 1, c))
    if r!=1: 
        adj.append(thick(r - 1, c))
    if c!=data['column'].max(): 
        adj.append(thick(r, c + 1))
    if c!=1: 
        adj.append(thick(r, c - 1))
    return adj

然而,我正在努力寻找一种方法将此函数应用于数据帧中的每个单元格。我尝试了iterrows,但由于实际数据集非常大,因此速度很慢。

任何有关如何向前推进的建议都将不胜感激。

1 个答案:

答案 0 :(得分:2)

正如@Paul建议的那样,你可能想在这里使用numpy。 Numpy是大熊猫的依赖,非常值得学习它自己和大熊猫的伴侣。对于您不需要大熊猫附加功能的情况,numpy解决方案可以更快。这是其中一种情况。

最棘手的部分是角落和边缘,我通过在外面放置一圈NaN来处理它。结合np.nanmean(而不是np.mean),这将使分母对于计算方法保持正确。虽然它已经是一个相当简洁的答案,但可能(或可能不)是一种更优雅的方式。

import numpy as np

arr = np.empty([5,5])
arr[:] = np.nan
arr[1:4,1:4] = np.arange(100,109).reshape(3,3)

或者,如果您需要将原始数据帧转换为numpy数组,则可以将最后一行替换为:

arr[1:4,1:4] = data.set_index(['row','column']).unstack().values

所以现在你的数组看起来像这样。

array([[  nan,   nan,   nan,   nan,   nan],
       [  nan,  100.,  101.,  102.,   nan],
       [  nan,  103.,  104.,  105.,   nan],
       [  nan,  106.,  107.,  108.,   nan],
       [  nan,   nan,   nan,   nan,   nan]])

此后你需要np.nanmean

np.nanmean( np.array( [ arr[1-1:4-1,1:4], arr[1:4,1-1:4-1], 
                        arr[1+1:4+1,1:4], arr[1:4,1+1:4+1] ] ), axis=0 )

array([[ 102.        ,  102.        ,  103.        ],
       [ 103.33333333,  104.        ,  104.66666667],
       [ 105.        ,  106.        ,  106.        ]])