Python Pandas每日平均值

时间:2014-04-18 21:15:17

标签: python pandas

我在Pandas数据库中获得每日平均值时遇到问题。我在这里查了Calculating daily average from irregular time series using pandas但没有用。 csv文件如下所示:

Date/Time,Value
12/08/13 12:00:01,5.553
12/08/13 12:30:01,2.604
12/08/13 13:00:01,2.604
12/08/13 13:30:01,2.604
12/08/13 14:00:01,2.101
12/08/13 14:30:01,2.666

等等。我的代码如下所示:

# Import iButton temperatures
flistloc = '../data/iButtons/Readings/edit'
flist = os.listdir(flistloc)
# Create empty dictionary to store db for each file
pdib = {}
for file in flist:
    file = os.path.join(flistloc,file)
    # Calls function to return only name
    fname,_,_,_= namer(file)
    # Read each file to db
    pdib[fname] = pd.read_csv(file, parse_dates=0, dayfirst=True, index_col=0)
pdibkeys = sorted(pdib.keys())
#
# Calculate daily average for each iButton
for name in pdibkeys:
    pdib[name]['daily'] = pdib[name].resample('D', how = 'mean')```

数据库似乎没问题,但平均值不起作用。这是iPython中的样子:

'2B5DE4': <class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1601 entries, 2013-08-12 12:00:01 to 2013-09-14 20:00:01
Data columns (total 2 columns):
Value    1601  non-null values
daily    0  non-null values
dtypes: float64(2)}

任何人都知道发生了什么事?

3 个答案:

答案 0 :(得分:4)

问题有些陈旧,但我还是想做出贡献,因为我不得不一遍又一遍地处理这个问题(而且我认为它并不是真正的pythonic ......)。

迄今为止我提出的最佳解决方案是使用原始索引创建一个主要为NA的新数据框,并在最后填充它。

davg = df.resample('D', how='mean')
davg_NA = davg.loc[df.index]
davg_daily = davg_NA.fillna(method='ffill')

甚至可以在一行中解决这个问题

df.resample('D', how='mean').loc[df.index].fillna(method='ffill')

答案 1 :(得分:2)

当您在1列数据框上调用resample时,输出将是1列数据框,其中不同的索引 - 每个日期都作为自己的索引条目。因此,当您尝试将其分配给原始数据框中的列时,我不知道您希望发生什么。

三种可能的方法(df是您的原始数据框):

  1. 您确实需要原始数据框中的平均值吗?如果不是:

    davg = df.resample('D', how='mean')

  2. 如果这样做,另一个解决方案是在确保两个数据帧都具有日期的列(而不是索引)之后合并日期上的两个数据帧。

  3. davg = df.resample('D', how='mean')
    df['day'] = df.index.apply(lambda x: x.date()) 
    davg.reset_index('Date/Time', inplace=True)
    df = pandas.merge(df, davg, left_on='day',right_on='Date/Time')
    
    1. 2的替代(没有关于它是否更快的直觉)只是groupby日期。

      def compute_avg_val(df):
          df['daily average'] = df['Value'].mean()
          return df
      df['day'] = df.index.apply(lambda x: x.date())
      grouped = df.groupby('day')
      df = grouped.apply(compute_avg_val)
      

答案 2 :(得分:2)

您无法以较低的频率重新取样,然后将重新取样的DataFrameSeries分配回您重新取样的那个,因为索引不匹配:

In [49]: df = pd.read_csv(StringIO("""Date/Time,Value
12/08/13 12:00:01,5.553
12/08/13 12:30:01,2.604
12/08/13 13:00:01,2.604
12/08/13 13:30:01,2.604
12/08/13 14:00:01,2.101
12/08/13 14:30:01,2.666"""), parse_dates=0, dayfirst=True, index_col=0)

In [50]: df.resample('D')
Out[50]:
            Value
Date/Time
2013-08-12  3.022

[1 rows x 1 columns]

In [51]: df['daily'] = df.resample('D')

In [52]: df
Out[52]:
                     Value  daily
Date/Time
2013-08-12 12:00:01  5.553    NaN
2013-08-12 12:30:01  2.604    NaN
2013-08-12 13:00:01  2.604    NaN
2013-08-12 13:30:01  2.604    NaN
2013-08-12 14:00:01  2.101    NaN
2013-08-12 14:30:01  2.666    NaN

[6 rows x 2 columns]

一种选择是利用对行的部分时间索引:

davg = df.resample('D', how='mean')
df.loc[str(davg.index.date[0]), 'daily'] = davg.values
当您展开str(davg.index.date[0])行时,

看起来像这样:

df.loc['2013-08-12', 'daily'] = davg.values

这有点破解,可能有更好的方法。