【问题标题】:How to use Pandas to block average data frame with a length of 10 frames?如何使用 Pandas 阻止平均长度为 10 帧的数据帧?
【发布时间】:2017-06-12 15:56:04
【问题描述】:

我是熊猫新手。所以我想知道是否有一些方法可以更好地完成这项任务。

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

这是来自分子动力学的 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 Frames 的平均值,2 代表 Frame 11 ~ 20。

虽然,我认为通过仔细分配每一行的索引我可以完成这些任务,我想知道是否有一些方便的方法来完成这个任务。我检查了一些关于pandasgroupby 函数的网页,似乎没有这个组每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....,并在每组中,对每个碱基对进行平均。

这是我计算出来的数据:

    # -*- 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:试图在一个副本上设置一个值 从 DataFrame 切片。尝试使用 .loc[row_indexer,col_indexer] = 取而代之的价值

请参阅文档中的注意事项: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy GPtemp['Frame'] = str(i) /home/iphyer/Downloads/dataProcessing.py:62: SettingWithCopyWarning:试图在一个副本上设置一个值 从 DataFrame 切片。尝试使用 .loc[row_indexer,col_indexer] = 取而代之的价值

请参阅文档中的注意事项: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy GPtemp['Frame'] = str(i)

我想知道:

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

最好的!

【问题讨论】:

  • 假设你的数据框被称为df,你可以这样做:df.groupby(df['#Frame']//10).mean()。此外,您可能应该将列 #Frame 重命名为 Frame
  • @Abdou,谢谢,我已经更新了描述。现在又出现了一些新问题。

标签: python python-3.x pandas pandas-groupby


【解决方案1】:

可以通过多种方式在 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

【讨论】:

  • 嗨,@Woody Pride,我已经尝试过您的解决方案,但结果如下所示:` #Frame Base1 Base2 Shear Stretch Stagger Buckle \ 0 485.803153 16.995941 50.004059 0.017325 -0.042114 0.067136 1.731197 ` 但是我想要保持第一帧的原始结构。
  • 例如,我不仅要维护 Base1 Base2 记录的均值,还要维护每个均值。
  • 恐怕我不明白你的问题。如果您想用一个可重复的小示例和预期输出来更新您的问题,那么也许有人会发布更完整的解决方案。
猜你喜欢
  • 2019-09-01
  • 2022-07-28
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多