动态访问pandas dataf rame的子集,执行计算并写入新数据帧

时间:2018-04-08 06:25:55

标签: python pandas dataframe dynamic subquery

我有一个非常大的数据框,我想从中抽取一个子样本,执行一些计算,然后将这些结果写入一个新的数据框。如需样本,请考虑:

df_test = pd.DataFrame(np.random.randint(low=0, high=10, size=(5, 5)),
                    columns=['a', 'b', 'c', 'd', 'e'])
df_test

归还:

    a   b   c   d   e
0   1   9   0   3   0
1   5   4   1   0   3
2   9   3   6   3   5
3   6   2   5   9   7
4   9   0   7   9   5

现在我想"提取"总是3行,从头开始滚动并计算每列的平均值(例如,其他计算也会起作用):

df_1
    a   b   c   d   e
0   1   9   0   3   0
1   5   4   1   0   3
2   9   3   6   3   5

df_2 
    a   b   c   d   e
1   5   4   1   0   3
2   9   3   6   3   5
3   6   2   5   9   7

df_3 
    a   b   c   d   e
2   9   3   6   3   5
3   6   2   5   9   7
4   9   0   7   9   5

结果数据框是

result
    a   b   c   d   e
0   5   5.3 2.3 3   2.7
1   6.7 3   4   4   5
2   8   1.7 6   7   5.3

我该怎么做?

1 个答案:

答案 0 :(得分:3)

使用rolling并按ilocdropna删除前NaN行:

N = 3
df = df.rolling(N).mean().iloc[N-1:]
df = df.rolling(3).mean().dropna(how='all')

print (df)
          a         b         c    d         e
2  5.000000  5.333333  2.333333  2.0  2.666667
3  6.666667  3.000000  4.000000  4.0  5.000000
4  8.000000  1.666667  6.000000  7.0  5.666667

如果还需要mean的第一行,第一行+第二行添加参数min_periods

df1 = df.rolling(3, min_periods=1).mean()
print (df1)
          a         b         c    d         e
0  1.000000  9.000000  0.000000  3.0  0.000000
1  3.000000  6.500000  0.500000  1.5  1.500000
2  5.000000  5.333333  2.333333  2.0  2.666667
3  6.666667  3.000000  4.000000  4.0  5.000000
4  8.000000  1.666667  6.000000  7.0  5.666667

编辑:

手动aproach应创建一行DataFrame,然后将所有行连接起来:

dfs = []
N = 3
for x in np.arange(len(df)+1)[N:]:
    df1 = df.iloc[np.arange(x - N, x)]
    #print (df1)
    s = df1.mean().to_frame().T
    #print (s)
    dfs.append(s)

df2 = pd.concat(dfs, ignore_index=True)
print (df2)
          a         b         c    d         e
0  5.000000  5.333333  2.333333  2.0  2.666667
1  6.666667  3.000000  4.000000  4.0  5.000000
2  8.000000  1.666667  6.000000  7.0  5.666667