首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何有效地将熊猫数据帧重采样为3d NumPy数组?

如何有效地将熊猫数据帧重采样为3d NumPy数组?
EN

Stack Overflow用户
提问于 2020-06-18 05:31:23
回答 1查看 332关注 0票数 0

我有一个包含DatetimeIndex和多列的大数据框架。现在我想要有一个操作resample_3d,它可以像这样使用:

代码语言:javascript
运行
复制
index, array = df.resample_3d("1h", fill_value=0)

..。并对数据帧进行变换

代码语言:javascript
运行
复制
index | A | B | C | D
10:00 | 1 |   | 
10:01 | 1 |   | 
12:00 | 1 |   |
13:00 | 1 |   |

转换为形状(3,2,4)的3d-NumPy数组。第一个维度是时间(可以在单独返回的index中查找),第二个维度是“重采样组”中的行索引,第三个维度是特征。第二个维度的大小等于单个重采样组中的最大行数。未使用的条目被填充(例如,用零填充)。

在Pandas /另一个库中有这样或类似的函数吗?或者有没有一种方法可以在Pandas之上高效地实现这样的功能,而不需要太多的工作?

我意识到我可以在df.resample().apply(list)之上构建一些东西,但对于更大的数据帧来说,这太慢了。

我已经开始了自己的Numba实现,但很快就意识到这是一项相当繁重的工作。

(我刚刚发现了xarray,我想我用它来标记这个问题,因为它可能是比Pandas更好的基础。)

EN

回答 1

Stack Overflow用户

发布于 2020-07-04 04:17:17

不清楚你的数据是什么样子的,但是的,xarray可能就是你要搜索的。

一旦您的数据被格式化为DataArray,您就可以这样做:

代码语言:javascript
运行
复制
da.resample(time="1h")

它将返回一个DataArrayResample对象。

通常,重采样时,新的坐标栅格与以前的栅格不匹配。

因此,您需要应用众多methods of the DataArrayResample object中的一个来告诉xarray如何填充这个新网格。

例如,您可能希望使用原始数据作为结来插入值:

代码语言:javascript
运行
复制
da.resample(time="1h").interpolate("linear")

但你也可以回填,填充,使用最接近的值等。

如果你不想填充新的网格,使用.asfreq(),新的时间将被设置为NaN。稍后,您仍然可以使用interpolate_na()进行插值。

你的案例

在您的例子中,您似乎正在进行下采样,因此在新的网格坐标和原始网格坐标之间存在精确匹配。

因此,适用于您的方法是.nearest().asfreq().interpolate() (请注意,.interpolate()会将int转换为float)。

但是,由于您是在精确的网格节点处进行下采样,因此您真正要做的是选择数组的一个子集,因此您可能希望使用.sel()方法。

示例

对精确网格点节点进行下采样的一个示例。

创建数据:

代码语言:javascript
运行
复制
>>> dims = ("time", "features")
>>> sizes = (6, 3)
>>> h_step = 0.5

>>> da = xr.DataArray(
        dims=dims,
        data=np.arange(np.prod(sizes)).reshape(*sizes),
        coords=dict(
            time=pd.date_range(
                "04/07/2020",
                periods=sizes[0],
                freq=pd.DateOffset(hours=h_step),
            ),
            features=list(string.ascii_uppercase[: sizes[1]]),
        ),
    )

>>> da
<xarray.DataArray (time: 6, features: 3)>
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])
Coordinates:
  * time      (time) datetime64[ns] 2020-04-07 ... 2020-04-07T02:30:00
  * features  (features) <U1 'A' 'B' 'C'

>>> da.time.values
array(['2020-04-07T00:00:00.000000000',
       '2020-04-07T00:30:00.000000000',
       '2020-04-07T01:00:00.000000000', 
       '2020-04-07T01:30:00.000000000',
       '2020-04-07T02:00:00.000000000',
       '2020-04-07T02:30:00.000000000'],
      dtype='datetime64[ns]')

使用.resample().nearest()进行下采样

代码语言:javascript
运行
复制
>>> da.resample(time="1h").nearest()
<xarray.DataArray (time: 3, features: 3)>
array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14]])
Coordinates:
  * time      (time) datetime64[ns] 2020-04-07 ... 2020-04-07T02:00:00
  * features  (features) <U1 'A' 'B' 'C'

>>> da.resample(time="1h").nearest().time.values
array(['2020-04-07T00:00:00.000000000',
       '2020-04-07T01:00:00.000000000',
       '2020-04-07T02:00:00.000000000'],
      dtype='datetime64[ns]')

按选择进行下采样:

代码语言:javascript
运行
复制
>>> dwn_step = 2

>>> new_time = pd.date_range(
        "04/07/2020",
        periods=sizes[0] // dwn_step,
        freq=pd.DateOffset(hours=h_step * dwn_step),
    )

>>> da.sel(time=new_time)
<xarray.DataArray (time: 3, features: 3)>
array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14]])
Coordinates:
  * time      (time) datetime64[ns] 2020-04-07 ... 2020-04-07T02:00:00
  * features  (features) <U1 'A' 'B' 'C'

>>> da.sel(time=new_time).time.values
array(['2020-04-07T00:00:00.000000000',
       '2020-04-07T01:00:00.000000000',
       '2020-04-07T02:00:00.000000000'],
      dtype='datetime64[ns]')

创建new_time索引的另一种选择是仅执行以下操作:

代码语言:javascript
运行
复制
new_time = da.time[::dwn_coeff]

它更简单,但您不能选择第一个选择的时间(这可能是好的,也可能是坏的,取决于您的情况)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62438708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档