2017-04-17 80 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