我有一個由25萬個專案組成的資料集,在被添加到一個串列/生成器之前需要滿足某些標準。為了加快處理速度,我想使用生成器,但我不確定是否要用一個產生過濾樣本的函式來過濾資料,或者是否應該直接將過濾后的樣本回傳給生成器物件,等等。我希望最終的物件只包括符合過濾條件的樣本,但默認情況下python會回傳/產生一個NoneType物件。 我已經包括了過濾器函式的例子、資料(真正的問題使用的是字串,但是為了簡單起見,我使用的是隨機正態分布中的浮點數),以及我打算對下面的資料做什么。
在這種情況下,我應該如何有效地使用生成器?在這種情況下使用生成器是否符合邏輯/有效?我知道我可以檢查回傳函式中的元素是否為 None,從而將其從容器(串列/生成器)中排除,但是我如何在產生值的函式中這樣做呢?
# For random data。
import numpy as np
# Functions[/span
def filter_and_yield(item_in_data)。
if item_in_data > 0.0:
yield item_in_data
def filter_and_return(item_in_data)。
if item_in_data > 0.0:
return item_in_data
# Arbitrary data: return item_in_data.
num_samples = 250 * 10 **3
data = np.random.normal(size=(num_samples,))
# Should I use this: generator with generator elements?
filtered_data_as_gen_with_gen_elements = (filter_and_yield(item) for item in data)
# Should I use this: list with generator elements?
filtered_data_as_lst_with_gen_elements = [filter_and_yield(item) for item in data]
# Should I use this: generator with non-generator elements?
filtered_data_as_gen_with_non_gen_elements = (
filter_and_return(item) for item in data if filter_and_return(item) is not None)
# Should I use this: list with non-generator elements?
filtered_data_as_lst_with_non_gen_elements = [
filter_and_return(item) for item in data if filter_and_return(item) is not None]
# 保存資料為csv -- 注意,`filtered_data`沒有被定義]
# 但它是一個占位符,用來表示對資料進行過濾的正確方式。
df = pd.DataFrame({'filtered_data'/span>: filtered_data})
df.to_csv('./filtered_data.csv')
uj5u.com熱心網友回復:
簡短的回答是,這些都不是最好的。Numpy和pandas包含了大量的C和Fortan代碼,這些代碼在存盤于連續陣列的硬體級資料型別上作業。Python物件,即使是像int和float這樣的低級物件也是相對笨重的。它們包括標準的python物件頭,并在堆上分配。甚至像>這樣的簡單操作也需要呼叫它的一個方法。
最好盡可能地使用 numpy/pandas 函式和運算子。這些包已經多載了標準的Python運算子,以便在一次呼叫中處理整個資料集。
df = pd.DataFrame({'filtered_data': data[data > 0.0]})
在這里,data > 0.0創建了一個新的真/假的numpy陣列用于比較。data[...]創建了一個新的陣列,只保存data的值也是真的。
其他說明
filter_and_yield是一個生成器,它將迭代0或1的值。Python 把它變成了一個生成器,因為它有一個 yield。當它回傳None時,Python將它變成一個StopIteration例外。這個生成器的消費者將不會看到None。
(filter_and_yield(item) for item in data)是一個回傳生成器的發生器。如果你使用它,你將會得到一列生成器的資料框架。
[filter_and_yield(item) for item in data]是一個生成器的串列(因為filter_and_yield是一個生成器)。當pandas創建一個列時,它需要知道列的大小。所以它把生成器擴展成串列,就像你在這里做的那樣。你可以為pandas做這個,其實并不重要。除了pandas會在完成后洗掉該串列,從而減少記憶體的使用。
(filter_and_return(item)) for item in data if filter_and_return(item) is not None) 這個可以作業,但是它很慢。data持有一個硬體級別的整數陣列。for item in data必須將這些整數轉換成Python級別的整數,而nfilter_and_return(item)是一個相對昂貴的函式呼叫。這可以改寫為(value for value in (filter_and_return(item) for item in data) if value is not None)以減少一半的函式呼叫。
[filter_and_return(item) for item in data if filter_and_return(item) is not None]如上所述,這樣做是可以的,但在完成后要洗掉,以節約記憶體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/326833.html
標籤:
下一篇:使用python進行曲線擬合
