Gui*_*ume 3 python numpy pandas
我想在numpy数组中找到相同值的块的起始和停止索引,或者最好是pandas DataFrame(沿着列的列为2D数组,沿着最快速变化的索引为 - 维数组).我只在单个维度上查找块,并且不希望在不同的行上聚集nans.
从那个问题开始(在numpy数组中查找满足条件的大量连续值),我编写了以下解决方案,为2D数组寻找np.nan:
import numpy as np
a = 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)
Run Code Online (Sandbox Code Playgroud)
这让我举例说明在应用pd.fillna之前分析缺失值的补丁长度的分布.
stop_col_idx - start_col_idx + 1
array([2, 1, 1, 4], dtype=int64)
Run Code Online (Sandbox Code Playgroud)
还有一个例子和期待的结果:
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)
Run Code Online (Sandbox Code Playgroud)
并不是
array([2, 1, 6], dtype=int64)
Run Code Online (Sandbox Code Playgroud)
我的问题如下:
我将你的np.array加载到一个数据帧中:
In [26]: df
Out[26]:
0 1 2 3
0 1 NaN NaN 2
1 NaN 1 NaN 2
2 NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
然后调换并将其变成一系列.我认为这类似于np.hstack:
In [28]: s = df.T.unstack(); s
Out[28]:
0 0 1
1 NaN
2 NaN
3 2
1 0 NaN
1 1
2 NaN
3 2
2 0 NaN
1 NaN
2 NaN
3 NaN
Run Code Online (Sandbox Code Playgroud)
此表达式创建一个Series,其中数字表示每个非空值递增1的块:
In [29]: s.notnull().astype(int).cumsum()
Out[29]:
0 0 1
1 1
2 1
3 2
1 0 2
1 3
2 3
3 4
2 0 4
1 4
2 4
3 4
Run Code Online (Sandbox Code Playgroud)
此表达式创建一个系列,其中每个nan为1,其他所有为零:
In [31]: s.isnull().astype(int)
Out[31]:
0 0 0
1 1
2 1
3 0
1 0 1
1 0
2 1
3 0
2 0 1
1 1
2 1
3 1
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式将两者结合起来,以实现您需要的计数:
In [32]: s.isnull().astype(int).groupby(s.notnull().astype(int).cumsum()).sum()
Out[32]:
1 2
2 1
3 1
4 4
Run Code Online (Sandbox Code Playgroud)