假設我有一個 numpy 陣列
my_array = [0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan]
對于每個 nan 值,我想在該點的左側和右側提取兩個非 nan 值(如果合適,也可以提取單個值)。所以我希望我的輸出類似于
output = [[0.3,0.1], [0.3,0.1], [0.3,0.1], [0.1,0.5], [0.5]]
我正在考慮遍歷 my_array 中的所有值,然后找到那些是 nan 的,但我不知道如何找到最近的非 nan 值的下一部分。
uj5u.com熱心網友回復:
使用 pandas 和 numpy:
s = pd.Series([0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan])
m = s.isna()
a = np.vstack((s.ffill()[m], s.bfill()[m]))
out = a[:,~np.isnan(a).any(0)].T.tolist()
輸出:
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5]]
注意。您可以選擇保留或洗掉包含 NaN 的串列。
使用 NaN:
out = a.T.tolist()
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5, nan]]
處理單個元素的替代方法:
s = pd.Series([0.2, 0.3, nan, nan, nan, 0.1, nan, 0.5, nan])
m = s.isna()
(pd
.concat((s.ffill()[m], s.bfill()[m]), axis=1)
.stack()
.groupby(level=0).agg(list)
.to_list()
)
輸出:
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5]]
uj5u.com熱心網友回復:
不如@mozway 的回答優雅,但最后一個串列只有一個元素:
pd.DataFrame({
'left':arr.ffill(),
'right': arr.bfill()
}).loc[arr.isna()].apply(lambda row: row.dropna().to_list(), axis=1).to_list()
uj5u.com熱心網友回復:
為了教育起見,我將發布一個非常簡單的演算法來實作這個結果,它的作業原理是在 NaN 的每個索引的左側和右側找到一個值的最接近的索引,并過濾掉任何 inf在末尾:
def get_neighbors(x: np.ndarray) -> list:
mask = np.isnan(x)
nan_idxs, *_ = np.where(mask)
val_idxs, *_ = np.where(~mask)
neighbors = []
for nan_idx in nan_idxs:
L, R = -float("inf"), float("inf")
for val_idx in val_idxs:
if val_idx < nan_idx:
L = max(L, val_idx)
else:
R = min(R, val_idx)
# casting to list isn't strictly necessary, you'll just end up with a list of arrays
neighbors.append(list(x[[i for i in (L, R) if i > 0 and i < float("inf")]]))
return neighbors
輸出:
>>> get_neighbors(my_array)
[[0.3, 0.1], [0.3, 0.1], [0.3, 0.1], [0.1, 0.5], [0.5]]
嵌套for回圈的最壞情況運行時O((n / 2)^2)是n元素的數量x(最壞情況發生在恰好一半的元素是 NaN 時)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/473649.html
標籤:Python 麻木的 楠 numpy-ndarray
下一篇:在Python中計算衰減率
