Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 跨多个列使用groupby减去列的平均值_Python_Pandas_Dataframe_Lambda - Fatal编程技术网

Python 跨多个列使用groupby减去列的平均值

Python 跨多个列使用groupby减去列的平均值,python,pandas,dataframe,lambda,Python,Pandas,Dataframe,Lambda,在多列中使用groupby应用此函数时遇到问题,但跳过了某些列 我的数据框如下所示: arr = pd.DataFrame( [[201207310930, 0.0022, -0.0160, 0.0055, 0.0324, -0.0328], [201207310930, 0.0040, -0.0073, 0.0293, 0.0465, -0.0275], [201207310930, -0.0095,-0.0080, 0.0215, 0.0525, -0.0317]

在多列中使用groupby应用此函数时遇到问题,但跳过了某些列

我的数据框如下所示:

arr = pd.DataFrame(
[[201207310930, 0.0022, -0.0160,    0.0055, 0.0324, -0.0328],
[201207310930,  0.0040, -0.0073,    0.0293, 0.0465, -0.0275],   
[201207310930,  -0.0095,-0.0080,    0.0215, 0.0525, -0.0317],   
[201207311030,  -0.0005,-0.0040,    -0.0149,    0.0135, 0.0488],
[201207311030,  -0.0087,-0.0240,    0.0134, 0.0480, -0.0331]]
)   
我想在datetime上分组,然后去趋势化(减去平均值),所以这就是我尝试过的(忽略x1列):

我的问题是,这只是输出一组零,我想它只是从x的平均值减去x,但是x的平均值只包括一个元素,而不是一组元素

预期的结果是一个新的数据帧,它将从每个元素中减去每个列中每个组的平均值:

201207310930    0.0033  -0.00556    -0.01326    -0.0114 -0.00213
201207310930    0.0051  0.00313      0.01053    0.0027  0.00316
201207310930    -0.0084 0.00243      0.00273    0.0087  -0.001033
201207311030    0.0041  0.01        -0.01415    -0.01725  0.04095
201207311030    -0.0041 -0.01        0.01415    0.01725 -0.04095

假设您有这个
df

Datetime x1 x2 x3 x4 x5
0  201207310930  0.0022 -0.0160  0.0055  0.0324 -0.0328
1  201207310930  0.0040 -0.0073  0.0293  0.0465 -0.0275
2  201207310930 -0.0095 -0.0080  0.0215  0.0525 -0.0317
3  201207311030 -0.0005 -0.0040 -0.0149  0.0135  0.0488
4  201207311030 -0.0087 -0.0240  0.0134  0.0480 -0.0331
然后:

detrendfunc=lambda x:(x-x.mean())

cols=df.columns[1::][p>您可以在第一列上设置索引,使用
transform
获得每组的平均值,同时保持形状,再次使用transform进行减法,然后重置索引:

(arr
 .set_index(0)
 .transform(lambda df: df - df.groupby(level=0)
                              .transform("mean")
            )
 .reset_index()
 )
 
              0       1         2         3        4         5
0  201207310930  0.0033 -0.005567 -0.013267 -0.01140 -0.002133
1  201207310930  0.0051  0.003133  0.010533  0.00270  0.003167
2  201207310930 -0.0084  0.002433  0.002733  0.00870 -0.001033
3  201207311030  0.0041  0.010000 -0.014150 -0.01725  0.040950
4  201207311030 -0.0041 -0.010000  0.014150  0.01725 -0.040950
另一种选择是分别对相关列进行计算,然后
更新
原始数据帧(注意,这会覆盖原始
arr
数据帧-您可以在运行更新之前复制数据帧):


内部变量是什么?
arr
?带有日期时间x1、x2…x5的数据帧。您可以编辑代码并将预期结果放在那里吗?好的,我已经添加了预期结果,并演示了如何创建arr。您知道~50GB数据帧的最快速度是哪一个吗?最后一个可能是最快的,因为它只计算每个组的平均值一次,当其他选项为每个组中的每个元素计算每个组的平均值时?对于50GB,可能不会想到Pandas您建议将其转储到sql中?可能使用sqlite。或者,如果您熟悉R,可以使用
data.table
。在python中,可以使用
pydatatable
。不过,我首先要介绍SQLite,我假设您对SQL有一点了解(这类似于windows操作)
(arr
 .set_index(0)
 .transform(lambda df: df - df.groupby(level=0)
                              .transform("mean")
            )
 .reset_index()
 )
 
              0       1         2         3        4         5
0  201207310930  0.0033 -0.005567 -0.013267 -0.01140 -0.002133
1  201207310930  0.0051  0.003133  0.010533  0.00270  0.003167
2  201207310930 -0.0084  0.002433  0.002733  0.00870 -0.001033
3  201207311030  0.0041  0.010000 -0.014150 -0.01725  0.040950
4  201207311030 -0.0041 -0.010000  0.014150  0.01725 -0.040950
arr.update(arr.iloc[:, 1:] - arr.groupby(0).transform("mean"))

arr
           0       1         2         3        4         5
0  201207310930  0.0033 -0.005567 -0.013267 -0.01140 -0.002133
1  201207310930  0.0051  0.003133  0.010533  0.00270  0.003167
2  201207310930 -0.0084  0.002433  0.002733  0.00870 -0.001033
3  201207311030  0.0041  0.010000 -0.014150 -0.01725  0.040950
4  201207311030 -0.0041 -0.010000  0.014150  0.01725 -0.040950