2017-04-17 307 views
2

我有一個巨大的SQLite數據庫,當讀入一個大塊熊貓會導致內存錯誤。解決通常的方法是設置一個chunksize參數:跨大塊熊貓填充

db = 'rawdb.sqlite' 
conn = sqlite3.connect(db) 
SQL = 'SELECT * FROM Table' 

df = pd.read_sql(SQL, conn, chunksize=10000) 

我試圖清理在數據庫中的數據(2密耳行×141列),通過:

  1. 刪除任何一行超過32個NaN
  2. 正向填不下降

我可以提取我所需要的數據,如果它是一個唱行的所有其他NaN值樂塊:

df[~(df.isnull().sum(axis=1) > 32)].fillna(method='ffill') 

如何跨越塊做到這一點?具體而言,由於chunksize = 10000,下一塊將會從10001點的數據開始,如果行10001恰好包含NaN值,行不掉線,這是假設從行10000

但是到ffill,行10000在前面的塊中,所以沒有提及填充。這會導致行10001 NaN值未被填充。什麼是模板算法來解決這類問題?

+0

爲什麼在閱讀完所有大塊後最後兩個步驟不乾淨? – Parfait

+0

現在你的問題得到了解答,你能回答我的問題嗎?性能問題是不是最後清理? – Parfait

+0

這不是性能問題。你無法將整個文件讀入內存中,因爲它太大了,所以你可以通過分塊讀取它們,操縱並存儲它,卸載當前塊並讀取下一個文件。 – Yeile

回答

2

在遍歷塊時,可以保存上一次迭代的最後一行,並使用它填充新塊的第一行中的缺失值。例如:

lastrow = pd.Series() # initialize with empty Series 
for chunk in pd.read_sql(SQL, conn, chunksize=10000): 
    chunk = chunk[chunk.isnull().sum(axis=1) <= 32] 
    # fillna for the first row 
    chunk.iloc[0,:] = chunk.iloc[0,:].fillna(lastrow) 
    # fillna for the rest 
    chunk.fillna(method='ffill', inplace=True) 
    # do something with chunk 
    # ... 
    # save last row for next chunk 
    lastrow = chunk.iloc[-1,:] 
+0

從技術上講,由於混合數據類型,列是「pd.Series」,行是「pd.DataFrame」。 – Parfait