从系列构建新的数据框架

时间:2013-12-19 18:51:44

标签: python-2.7 pandas

在我older question的另一个裂缝,因为我仍然不明白如何正确地做我想要的。

我将数据存储在数据框中,需要提取它的平均块以便以后使用。我的索引是日期时间值,但这并不是非常重要。不幸的是,我不能做一个简单的df.resample()操作,因为我需要提取的数据不是有规律的间隔。示例:

import pandas as pd
from numpy import *

# Build example dataframe
df = pd.DataFrame(data=random.rand(10,3),index=None,columns=list('ABC'))

# Build dummy dataframe to store averaged data from "df"
dummy = pd.DataFrame(columns=df.columns)

# Perform averaging of "df" 
for r in xrange(1,10,2):
    ave = df.ix[r-1:r+1].mean()

    # Store averaged data in dummy dataframe
    # Here is where I hit my problem, since ave is a Series
    dummy = dummy.append(ave)

我无法在数据框中追加系列。
我可以通过将ave转换为字典,然后附加到dummy:

来解决
for r in xrange(1,10,2):
    ave = df.ix[r-1:r+1].mean().to_dict()
    ave = pd.DataFrame(ave,index=[r])
    dummy = dummy.append(ave)

首先:我的总体目标是否有意义? 第二:有没有更好的方法来实现这一目标?转换为字典,然后是数据帧,然后附加似乎是kludgey,但它是我所拥有的最好的。

开始编辑 unutbu提出了一个好点。如上所述,rolling_mean()将起作用。但是,我只对很少的数据行感兴趣,其他一切都被认为是垃圾。

# Now creating larger dataframe for illustration
df = pd.DataFrame(data=random.rand(10000,3),index=None,columns=list('ABC'))

# Now, most of the data are not averaged
for r in xrange(1,10000,50):
    ave = df.ix[r-1:r+1].mean().to_dict()
    ave = pd.DataFrame(ave,index=[r])

我的例子中的主要问题是显示平均值的不规则性。平均值是事件驱动的(即如果事情发生在2013-01-01 14:23那么平均数据有关2013-01-01 14:23 +/- 2.5min。

不幸的是,数据时间戳也非常不规则,这使得rolling_mean()在这种情况下无效。所以我有不规则的事件,确定我应该平均我的不规则记录数据,做一个很好的问题。

我可以实现我想要的,但只能将ave从系列转换为字典,然后转换为数据帧。也许在这种情况下,“足够好”应该更不用说了。

结束编辑         dummy = dummy.append(ave)

2 个答案:

答案 0 :(得分:3)

听起来你正在寻找的是pd.rolling_mean

import pandas as pd
import numpy as np

np.random.seed(1)
# Build example dataframe
df = pd.DataFrame(data=np.random.rand(10,3), index=None, columns=list('ABC'))
print(df)
#           A         B         C
# 0  0.417022  0.720324  0.000114
# 1  0.302333  0.146756  0.092339
# 2  0.186260  0.345561  0.396767
# 3  0.538817  0.419195  0.685220
# 4  0.204452  0.878117  0.027388
# 5  0.670468  0.417305  0.558690
# 6  0.140387  0.198101  0.800745
# 7  0.968262  0.313424  0.692323
# 8  0.876389  0.894607  0.085044
# 9  0.039055  0.169830  0.878143

dummy = pd.rolling_mean(df, window=3).dropna()
print(dummy)

产量

          A         B         C
2  0.301872  0.404214  0.163073
3  0.342470  0.303837  0.391442
4  0.309843  0.547624  0.369792
5  0.471245  0.571539  0.423766
6  0.338436  0.497841  0.462274
7  0.593039  0.309610  0.683919
8  0.661679  0.468711  0.526037
9  0.627902  0.459287  0.551836

答案 1 :(得分:2)

这是另一种具有日期索引的方法。

In [67]: df = pd.DataFrame(data=np.random.rand(10,3), index=None, columns=list('ABC'))

In [68]: df
Out[68]: 
          A         B         C
0  0.417022  0.720324  0.000114
1  0.302333  0.146756  0.092339
2  0.186260  0.345561  0.396767
3  0.538817  0.419195  0.685220
4  0.204452  0.878117  0.027388
5  0.670468  0.417305  0.558690
6  0.140387  0.198101  0.800745
7  0.968262  0.313424  0.692323
8  0.876389  0.894607  0.085044
9  0.039055  0.169830  0.878143

这是一个常规索引,但时间不规则(或至少是假装)

In [69]: df.index=date_range('20130101 09:00:58',periods=10,freq='s')

In [70]: df
Out[70]: 
                            A         B         C
2013-01-01 09:00:58  0.417022  0.720324  0.000114
2013-01-01 09:00:59  0.302333  0.146756  0.092339
2013-01-01 09:01:00  0.186260  0.345561  0.396767
2013-01-01 09:01:01  0.538817  0.419195  0.685220
2013-01-01 09:01:02  0.204452  0.878117  0.027388
2013-01-01 09:01:03  0.670468  0.417305  0.558690
2013-01-01 09:01:04  0.140387  0.198101  0.800745
2013-01-01 09:01:05  0.968262  0.313424  0.692323
2013-01-01 09:01:06  0.876389  0.894607  0.085044
2013-01-01 09:01:07  0.039055  0.169830  0.878143

获取每3个数据(无论是否为数据)并表示它(或者如果你愿意,你可以做得更好)。他们有更多的选择(例如,包括哪一方,在哪里放标签等,请参阅here

In [71]: df.resample('3s',how=lambda x: x.mean())
Out[71]: 
                            A         B         C
2013-01-01 09:00:57  0.359677  0.433540  0.046226
2013-01-01 09:01:00  0.309843  0.547624  0.369792
2013-01-01 09:01:03  0.593039  0.309610  0.683919
2013-01-01 09:01:06  0.457722  0.532219  0.481593