当前位置: 首页 > 面试题库 >

在Pandas MultiIndex中重新采样

宋臻
2023-03-14
问题内容

我有一些层次结构数据,这些数据触底到达时间序列数据,看起来像这样:

df = pandas.DataFrame(
    {'value_a': values_a, 'value_b': values_b},
    index=[states, cities, dates])
df.index.names = ['State', 'City', 'Date']
df

                               value_a  value_b
State   City       Date                        
Georgia Atlanta    2012-01-01        0       10
                   2012-01-02        1       11
                   2012-01-03        2       12
                   2012-01-04        3       13
        Savanna    2012-01-01        4       14
                   2012-01-02        5       15
                   2012-01-03        6       16
                   2012-01-04        7       17
Alabama Mobile     2012-01-01        8       18
                   2012-01-02        9       19
                   2012-01-03       10       20
                   2012-01-04       11       21
        Montgomery 2012-01-01       12       22
                   2012-01-02       13       23
                   2012-01-03       14       24
                   2012-01-04       15       25

我想对每个城市进行时间重采样,所以类似

df.resample("2D", how="sum")

将输出

                             value_a  value_b
State   City       Date                        
Georgia Atlanta    2012-01-01        1       21
                   2012-01-03        5       25
        Savanna    2012-01-01        9       29
                   2012-01-03       13       33
Alabama Mobile     2012-01-01       17       37
                   2012-01-03       21       41
        Montgomery 2012-01-01       25       45
                   2012-01-03       29       49

就这样,df.resample('2D', how='sum')让我

TypeError: Only valid with DatetimeIndex or PeriodIndex

足够公平,但是我有点希望这能起作用:

>>> df.swaplevel('Date', 'State').resample('2D', how='sum')
TypeError: Only valid with DatetimeIndex or PeriodIndex

在这一点上,我真的没什么主意了……是否有某种方法可以帮助我解决问题?


问题答案:

pd.Grouper
允许您指定“目标对象的groupby指令”。特别是,即使df.index不是,您也可以使用它按日期分组DatetimeIndex

df.groupby(pd.Grouper(freq='2D', level=-1))

level=-1讲述pd.Grouper寻找在多指标的最后一个级别的日期。此外,您可以将其与索引中的其他级别值结合使用:

level_values = df.index.get_level_values
result = (df.groupby([level_values(i) for i in [0,1]]
                      +[pd.Grouper(freq='2D', level=-1)]).sum())

它看起来有些尴尬,但using_Grouper比我最初的建议要快得多using_reset_index

import numpy as np
import pandas as pd
import datetime as DT

def using_Grouper(df):
    level_values = df.index.get_level_values
    return (df.groupby([level_values(i) for i in [0,1]]
                       +[pd.Grouper(freq='2D', level=-1)]).sum())

def using_reset_index(df):
    df = df.reset_index(level=[0, 1])
    return df.groupby(['State','City']).resample('2D').sum()

def using_stack(df):
    # http://stackoverflow.com/a/15813787/190597
    return (df.unstack(level=[0,1])
              .resample('2D').sum()
              .stack(level=[2,1])
              .swaplevel(2,0))

def make_orig():
    values_a = range(16)
    values_b = range(10, 26)
    states = ['Georgia']*8 + ['Alabama']*8
    cities = ['Atlanta']*4 + ['Savanna']*4 + ['Mobile']*4 + ['Montgomery']*4
    dates = pd.DatetimeIndex([DT.date(2012,1,1)+DT.timedelta(days = i) for i in range(4)]*4)
    df = pd.DataFrame(
        {'value_a': values_a, 'value_b': values_b},
        index = [states, cities, dates])
    df.index.names = ['State', 'City', 'Date']
    return df

def make_df(N):
    dates = pd.date_range('2000-1-1', periods=N)
    states = np.arange(50)
    cities = np.arange(10)
    index = pd.MultiIndex.from_product([states, cities, dates], 
                                       names=['State', 'City', 'Date'])
    df = pd.DataFrame(np.random.randint(10, size=(len(index),2)), index=index,
                      columns=['value_a', 'value_b'])
    return df

df = make_orig()
print(using_Grouper(df))

产量

                               value_a  value_b
State   City       Date                        
Alabama Mobile     2012-01-01       17       37
                   2012-01-03       21       41
        Montgomery 2012-01-01       25       45
                   2012-01-03       29       49
Georgia Atlanta    2012-01-01        1       21
                   2012-01-03        5       25
        Savanna    2012-01-01        9       29
                   2012-01-03       13       33

这里是一个标杆比较using_Grouperusing_reset_indexusing_stack在一个有5000行数据帧:

In [30]: df = make_df(10)

In [34]: len(df)
Out[34]: 5000

In [32]: %timeit using_Grouper(df)
100 loops, best of 3: 6.03 ms per loop

In [33]: %timeit using_stack(df)
10 loops, best of 3: 22.3 ms per loop

In [31]: %timeit using_reset_index(df)
1 loop, best of 3: 659 ms per loop


 类似资料:
  • 我正在用ffmpeg从flac文件制作mp3。这对我来说通常是哼哼。 今晚,由于某种原因,当我使用我一直使用的相同命令时,转换后的音频会失真。_故障排除后,出现“采样率”标志。 我的命令: MP3中的音频然后被一个顶起的增益所扭曲,导致数字剪辑。 我尝试更新ffmpeg,然后问题仍然存在。我尝试过转换各种采样率(44.1k源文件,48k源文件,96k源文件)44.1k和48kmp3,问题仍然存在,

  • 问题内容: 我正在寻找如何以新的大小重新采样表示图像数据的numpy数组,最好选择插值方法(最近,双线性等)。我知道有 通过包装PIL的调整大小功能可以做到这一点。唯一的问题是,由于它使用PIL,因此numpy数组必须符合图像格式,最多可以提供4个“颜色”通道。 我希望能够使用任意数量的“彩色”通道来调整任意图像的大小。我想知道是否有简单的方法可以在scipy / numpy中执行此操作,或者是否

  • 问题内容: 给定下面的熊猫DataFrame: 我想对数据重新采样以每小时计数一次,同时按位置分组以生成如下所示的数据框: 我尝试了resample()和groupby()的各种组合,但是没有运气。我将如何处理? 问题答案: 在我的原始帖子中,我建议使用。如今,使用代替。语法在很大程度上是相同的,但现在已不支持。 此外,虽然只能按DatetimeIndex分组,但可以按日期时间 列进行分组,而您可

  • 主要内容:降采样,升采样,频率转换,插值处理数据重采样是将时间序列从一个频率转换至另一个频率的过程,它主要有两种实现方式,分别是降采样和升采样,降采样指将高频率的数据转换为低频率,升采样则与其恰好相反,说明如下: 方法 说明 降采样 将高频率(间隔短)数据转换为低频率(间隔长)。 升采样 将低频率数据转换为高频率。 Pandas 提供了 resample() 函数来实现数据的重采样。 降采样 通过 resample() 函数完成数据的降采样

  • 问题内容: 我想每天从某个小时开始(每天24小时)对TimeSeries进行重新采样。 喜欢: 结果我得到: 结果我希望: 几个星期前,你可以传递到参数,它的工作完全罚款。但现在它合并为。 我是否正在使用已修复的错误?我如何才能以高效且pythonic(或大熊猫)的方式获得期望的结果? 版本: python 2.7.3 熊猫0.9.0rc1(但在0.8.1中也不起作用) numpy 1.6.1 问

  • 28 重采样选项 音频重采样支持下面一些选项。 选项可以在ffmpeg工具集中采用-option value的形式进行设置,或者在aresample滤镜中以option=value形式设置,也可以通过libavutil/opt.h的API或明确设置在SwrContext选项中。 ich, in_channel_count 设置输入通道序数。默认为0。如果in_channel_layout被设置,则