我當然可以
a[a == 0] = something
將 0 的每個條目設定a為something。等效地,我可以寫
a[np.equal(a, 0)] = something
現在,想象a是一個dtype=object. 我不能寫,a[a is None]因為,當然,a它本身不是None。意圖很明確:我希望is可以像任何其他 ufunc 一樣廣播比較。檔案中的這個串列沒有像is-unfunc那樣列出。
為什么沒有,而且對我來說更有趣的是:什么是高性能替代品?
uj5u.com熱心網友回復:
這里有兩件事在起作用。
第一個(也是更重要的)是is直接在 Python 解釋器中實作的,沒有重定向到 dunder 方法的選項。Numpy 陣列,像許多其他物件一樣,有一個__eq__實作==操作的方法。a is None被近似地視為id(a) == id(None),在任何情況下都不能求助于逐元素實作。這就是python的作業原理。
第二個方面是 numpy 從根本上設計用于存盤數字。物件陣列是將物件參考存盤為數字的特殊情況。這似乎與串列存盤物件參考的方式相同,但僅在處理參考時相似。串列的元素始終是對物件的參考,例如,即使串列包含同構整數。的D型阿numpy的陣列int并沒有包含Python物件。陣列的每個連續元素都是原始二進制整數,而不是對 python 物件包裝器的參考。即使python允許您覆寫is運算子,按元素應用也是沒有意義的。
因此,如果要比較物件,請使用 python 串列:
mylist = [...]
mylist = [something if x is None else x for x in mylist]
如果您堅持使用 numpy 陣列,要么 (a) 使用數值陣列并None用其他東西標記元素,例如np.nan,要么 (b) 將陣列視為串列。您必須將id或應用is到每個元素,它們是python 構造,因此此時沒有“高性能”的方法來執行此操作,或者 (c) 僅使用==,這將觸發 python 級別的相等比較,這相當于is對于單身人士None。
uj5u.com熱心網友回復:
除了reshape不依賴dtype(itemsize除外)的操作和索引之外,物件 dtype 陣列的操作以串列理解速度執行,迭代元素并對每個元素應用適當的方法。有時該方法不存在,例如在執行np.sin.
為了說明這一點,請考慮以下評論之一中的陣列:
In [132]: a = np.array([1, None, 0, np.nan, ''])
In [133]: a
Out[133]: array([1, None, 0, nan, ''], dtype=object)
物件陣列測驗:
In [134]: a==None
Out[134]: array([False, True, False, False, False])
In [135]: timeit a==None
5.16 μs ± 73.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
等價的理解:
In [136]: [x is None for x in a]
Out[136]: [False, True, False, False, False]
In [137]: timeit [x is None for x in a]
1.52 μs ± 18.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
它更快,即使我們將結果轉換回陣列(不是一個便宜的步驟):
In [138]: timeit np.array([x is None for x in a])
4.67 μs ± 95.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
對陣列的串列版本進行迭代甚至更快:
In [139]: timeit np.array([x is None for x in a.tolist()])
2.52 μs ± 48.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
讓我們看看完整的賦值操作:
In [141]: a[[x is None for x in a.tolist()]]
Out[141]: array([None], dtype=object)
In [142]: %%timeit a1=a.copy()
...: a1[[x is None for x in a1.tolist()]] = np.nan
...:
...:
4.03 μs ± 10 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [143]: %%timeit a1=a.copy()
...: a1[a1==None] = np.nan
...:
...:
6.18 μs ± 28.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
通常需要注意的是,事情的規模可能會有所不同。
uj5u.com熱心網友回復:
numpy沒有None資料型別。如果a is None您的第一個問題是您嘗試從中獲取元素的部分None:
a[a is None]
但是,您可以擁有nan(不是數字),并且可以使用isnan. 請參閱:https : //numpy.org/doc/stable/reference/generated/numpy.isnan.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/350877.html
標籤:Python 麻木的 numpy-ufunc
