如何使用Pandas来屏蔽长度为10帧的平均数据帧?

How to use Pandas to block average data frame with a length of 10 frames?

我是 Pandas 的新手。所以我想知道是否有一些更好的方法来完成这个任务。

我有一个如下格式的数据框:

这是分子动力学的DNA模拟数据

数据集在这里:BPdata.csv

所以,这里总共有 1000 帧,我的目的是获取每 10 帧的平均值,所以,最后,我希望数据是这样的:

Block  Base1 Base2 Shear Stretch Stagger .....
 1     1      66     XX    XX     XX
 1     2      65     XX    XX     XX
...   ...     ...    ...   ...    ...
 1     33     34     XX    XX     XX

 2     1      66     XX    XX     XX
 2     2      65     XX    XX     XX
...   ...     ...    ...   ...    ...
 2     33     34     XX    XX     XX

 3     1      66     XX    XX     XX
 3     2      65     XX    XX     XX
...   ...     ...    ...   ...    ...
 3     33     34     XX    XX     XX


 4     1      66     XX    XX     XX
 4     2      65     XX    XX     XX
...   ...     ...    ...   ...    ...
 4     33     34     XX    XX     XX

其中Block 1代表第1~10帧的平均值,2代表第11~20帧的平均值。

虽然,我认为通过仔细分配每一行的索引我可以完成这些任务,但我想知道是否有一些方便的方法来完成这个任务。我检查了一些关于 pandas 中的 groupby 函数的网页,似乎没有每 10 行这个组来获得块平均函数。

谢谢!

=============================更新======== ============================

抱歉,我的目的描述不清楚,我已经找到了完成任务的方法和示例输出,以更好地说明我的目的。

对于双链DNA,我们知道它是具有AGCT的双螺旋结构,所以Base1表示DNA的一个碱基,Base2表示另一条链的互补碱基。两个相应的碱基通过氢键连接在一起。

喜欢:

Base1 : AAAGGGCCCTTT
        ||||||||||||
Base2 : TTTCCCGGGAAA

所以这里 BPdata.csv Base1 和 Base2 的每个组合都表示一对 DNA 碱基。

BPdata.csv 中,这是一个 33 个碱基对的 DNA,在不同的时间范围内模拟,标记为 1,2,3,4...1000。

然后我想将每 10 个时间帧分组在一起,例如 1~10,11~20,21~30....,并且在每个组中,对每个 Base 对进行平均。

这是我计算出的数据:

    # -*- coding: utf-8 -*-

    import pandas as pd

    '''

    Data Input

    '''


    # Import CSV data to Python


    BPdata = pd.read_csv("BPdata.csv", delim_whitespace = True, skip_blank_lines = False)
    BPdata.rename(columns={'#Frame':'Frame'}, inplace=True)

    '''

    Data Processing

    '''
    # constant block average parameters
    Interval20ns = 10
    IntervalInBPdata = 34


    # BPdataBlockAverageSummary
    LEN_BPdata = len(BPdata)

    # For Frame 1
    i = 1
    indexStarting = 0
    indexEnding =  0  

    indexStarting = indexEnding
    indexEnding =  Interval20ns * IntervalInBPdata * i - 1

    GPtemp = BPdata.loc[indexStarting : indexEnding]
    GPtemp['Frame'] = str(i)
    BPdata_blockOF1K_mean = GPtemp.groupby(['Frame','Base1','Base2']).mean()
    BPdata_blockOF1K_mean.loc[len(BPdata_blockOF1K_mean)] = str(i)
    # For Frame 2 and so on
    i = i + 1
    indexStarting = indexEnding + 1
    indexEnding =  Interval20ns * IntervalInBPdata * i - 1
    while ( indexEnding <= LEN_BPdata - 1):
        GPtemp = BPdata.loc[indexStarting : indexEnding]
        GPtemp['Frame'] = str(i)
        meanTemp = GPtemp.groupby(['Frame','Base1','Base2']).mean()
        meanTemp.loc[len(meanTemp)] = str(i)    
        BPdata_blockOF1K_mean = pd.concat([BPdata_blockOF1K_mean,meanTemp])
        i = i + 1
        indexStarting = indexEnding + 1
        indexEnding =  Interval20ns * IntervalInBPdata * i - 1

结果是这样的,这就是我想要的:

这是示例输出,BPdataresult.csv

但到目前为止我收到了警告:

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy GPtemp['Frame'] = str(i) /home/iphyer/Downloads/dataProcessing.py:62: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy GPtemp['Frame'] = str(i)

我想知道:

  1. 这个警告严重吗?
  2. 由于Pandasgroupby功能,现在data frame的索引是(Frame,Base1,Base2)的组合,怎么才能像原来那样把它们分开呢。而是将 #Frame 补充到 Block index.
  3. 我可以改进代码或使用更多 Pandas 方法来完成这项任务吗?

最好!

pandas 中的分组可以通过多种方式完成。其中一种方法是通过系列。因此,您可以传递一个包含 10 个行块的值的系列。解决方案的工作原理如下:

import pandas as pd
import numpy as np

#create datafram with 1000 rows
df = pd.DataFrame(np.random.rand(1000, 1)

#create series for grouping
groups_of_ten = pd.Series(np.repeat(range(int(len(df)/10)), 10))

#group the data
grouped = df.groupby(groups_of_ten)

#aggregate
grouped.agg('mean')

分组系列内部看起来是这样的:

In [21]: groups_of_ten.head(20)
Out[21]:
0     0
1     0
2     0
3     0
4     0
5     0
6     0
7     0
8     0
9     0
10    1
11    1
12    1
13    1
14    1
15    1
16    1
17    1
18    1
19    1