打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在Python / Numpy / Pandas中查找连续值块的开始和停止

我想在numpy数组中找到相同值的块的起始和停止索引,或者最好是pandas DataFrame(沿着列的列为2D数组,以及沿着n维数组的最快速变化的索引).我只在单个维度上查找块,并且不希望在不同的行上聚集nans.

从这个问题(Find large number of consecutive values fulfilling condition in a numpy array)开始,我编写了以下解决方案,为2D数组寻找np.nan:

import numpy as npa = np.array([        [1, np.nan, np.nan, 2],        [np.nan, 1, np.nan, 3],         [np.nan, np.nan, np.nan, np.nan]    ])nan_mask = np.isnan(a)start_nans_mask = np.hstack((np.resize(nan_mask[:,0],(a.shape[0],1)),                             np.logical_and(np.logical_not(nan_mask[:,:-1]), nan_mask[:,1:])                             ))stop_nans_mask = np.hstack((np.logical_and(nan_mask[:,:-1], np.logical_not(nan_mask[:,1:])),                            np.resize(nan_mask[:,-1], (a.shape[0],1))                            ))start_row_idx,start_col_idx = np.where(start_nans_mask)stop_row_idx,stop_col_idx = np.where(stop_nans_mask)

这让我举例说明在应用pd.fillna之前分析缺失值的补丁长度的分布.

stop_col_idx - start_col_idx   1array([2, 1, 1, 4], dtype=int64)

还有一个例子和期待的结果:

a = np.array([        [1, np.nan, np.nan, 2],        [np.nan, 1, np.nan, np.nan],         [np.nan, np.nan, np.nan, np.nan]    ])array([2, 1, 2, 4], dtype=int64)

并不是

array([2, 1, 6], dtype=int64)

我的问题如下:

>有没有办法优化我的解决方案(在一次掩码/操作中查找开始和结束)?
>熊猫中是否有更优化的解决方案? (即不仅仅是在DataFrame的值上应用mask / where的解决方案)
>当底层数组或DataFrame要大到适合内存时会发生什么?

解决方法:

我将你的np.array加载到一个数据帧中:

In [26]: dfOut[26]:    0   1   2   30   1 NaN NaN   21 NaN   1 NaN   22 NaN NaN NaN NaN

然后调换并将其变成一系列.我认为这类似于np.hstack:

In [28]: s = df.T.unstack(); sOut[28]:0  0     1   1   NaN   2   NaN   3     21  0   NaN   1     1   2   NaN   3     22  0   NaN   1   NaN   2   NaN   3   NaN

此表达式创建一个Series,其中数字表示每个非空值递增1的块:

In [29]: s.notnull().astype(int).cumsum()Out[29]:0  0    1   1    1   2    1   3    21  0    2   1    3   2    3   3    42  0    4   1    4   2    4   3    4

此表达式创建一个系列,其中每个nan为1,其他所有为零:

In [31]: s.isnull().astype(int)Out[31]:0  0    0   1    1   2    1   3    01  0    1   1    0   2    1   3    02  0    1   1    1   2    1   3    1

我们可以通过以下方式将两者结合起来,以实现您需要的计数:

In [32]: s.isnull().astype(int).groupby(s.notnull().astype(int).cumsum()).sum()Out[32]:1    22    13    14    4
来源:https://www.icode9.com/content-1-346651.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Pandas中文官档 ~ 基础用法1
PANDAS QUICK START 
Python 中 NaN 和 None 的详细比较
《Python数据分析常用手册》一、NumPy和Pandas篇
教你如何用50道练习打通Pandas
Python数据分析——Pandas数据结构和操作
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服