如何将具有所选行的平均值的行添加到数据框中

时间:2018-01-08 13:14:07

标签: python pandas pandas-groupby

我有一个像这样的pandas数据框: 数据由第一列中的3个副本组成。这些副本中的每一个都包含相同的元素,即它们各有2个序列,它们又由3种不同的类型组成:A,R2和R3。

Copy    sequence    type    ntv
1        1           A      0.45
1        1           R2     0.878
1        1           R3     1.234
1        2           A      -7.890
1        2           R2     2.345
1        2           R3     -0.871
2        1           A      -0.098
2        1           R2     -0.007
2        1           R3     9.089
2        2           A      1.567
2        2           R2     -0.764
2        2           R3     17.908
3        1           A      4.980
3        1           R2     2.34
3        1           R3     1.280
3        2           A      -9.189
3        2           R2     -7.09
3        2           R3     -0.009

我想创建一个类似于下面的数据框,这样对于同一副本中的每个序列,R2和R3的平均值在新行上给出为类型“R”。我的意思是,在副本1中,我如何找到每个序列的R2和R3的平均值。

Copy    sequence    type    ntv
1        1           A      0.45
1        1           R2     0.878
1        1           R3     1.234
1        1           R      1.056
1        2           A      -7.890
1        2           R2     2.345
1        2           R3     -0.871
1        2           R      0.737
2        1           A      -0.098
2        1           R2     -0.007
2        1           R3     9.089
2        1           R      4.541
2        2           A      1.567
2        2           R2     -0.764
2        2           R3     17.908
2        2           R      8.572
3        1           A      4.980
3        1           R2     2.34
3        1           R3     1.280
3        1           R      1.81
3        2           A      -9.189
3        2           R2     -7.09
3        2           R3     -0.009
3        2           R      -3.549

这是我到目前为止的代码:

avg_type = [(('R2','R3'),'R')]
for i in set(df['Copy']):
    cp = df[df['Copy'] == i]
    for i in set(df['sequence']):
        seq = df[df['sequence'] == i]        
    for oldname, newname in avg_type:
        avg = seq.loc[seq['type'].isin(oldname)]
        if len(avg) > 1:
            newrow = avg.loc[avg.index[0]]
            newrow['ntv'] = avg['ntv'].mean()
            newrow['type'] = newname
            df.loc[-1] = newrow     
            df.index += 1

我只是设法弄清楚如何找到每个序列的R2和R3的平均值(换句话说,我得到2个值而不是6个),但即使是新行也没有按照我的意愿正确放置。

如何扩展我的选择标准以考虑“复制”号码?我会很感激任何有关如何使用pandas或python进行操作的帮助或指示。提前致谢!

2 个答案:

答案 0 :(得分:4)

试试这个:

In [68]: df.append(
    ...:     df[df['type'].isin(['R2','R3'])]
    ...:       .groupby(['Copy','sequence'], as_index=False)
    ...:       ['ntv'].mean()
    ...:       .assign(type='R')) \
    ...:   .sort_values(['Copy','sequence'])[df.columns]
    ...:
Out[68]:
    Copy  sequence type      ntv
0      1         1    A   0.4500
1      1         1   R2   0.8780
2      1         1   R3   1.2340
0      1         1    R   1.0560
3      1         2    A  -7.8900
4      1         2   R2   2.3450
5      1         2   R3  -0.8710
1      1         2    R   0.7370
6      2         1    A  -0.0980
7      2         1   R2  -0.0070
..   ...       ...  ...      ...
11     2         2   R3  17.9080
3      2         2    R   8.5720
12     3         1    A   4.9800
13     3         1   R2   2.3400
14     3         1   R3   1.2800
4      3         1    R   1.8100
15     3         2    A  -9.1890
16     3         2   R2  -7.0900
17     3         2   R3  -0.0090
5      3         2    R  -3.5495

[24 rows x 4 columns]

答案 1 :(得分:1)

这也将生成类型" R"。您可以追加并排序,并指定类型" R"像MaxU的功能。

df.loc[df.loc[:,"type"] != "A" ].groupby( ("Copy","sequence") , as_index = False).mean()