我有一个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),我需要从以下计算的平均单元格值:
我需要将此计算应用于每个单元格。
我有以下定义的功能:
此函数提取特定单元格的单元格值:
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
,但由于实际数据集非常大,因此速度很慢。
任何有关如何向前推进的建议都将不胜感激。
答案 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. ]])