从Series开始创建大型pandas DataFrame

时间:2015-03-18 14:27:56

标签: python numpy pandas bigdata

我正在处理相当大规模的数据。作为参考,给定样品将具有~75,000,000行和15,000-20,000列。

截至目前,为了节省内存,我采用了创建系列列表的方法(每列是一个系列,所以~15K-20K系列每个包含~250K行)。然后我创建一个包含这些系列中每个索引的SparseDataFrame(因为正如您所注意到的,这是一个很大但不是非常密集的数据集)。问题是这变得非常慢,并且将每列附加到数据集需要几分钟。为了克服这个问题,我也尝试了对合并进行批处理(选择数据的一个子集,将它们合并到一个DataFrame,然后合并到我的主DataFrame中),但这种方法仍然太慢。缓慢意味着它每天仅处理~4000列,每次追加都会导致后续追加时间更长。

让我感到奇怪的一个部分是为什么我的主DataFrame的列数会影响追加速度。因为我的主索引已经包含它将看到的所有条目,所以我不应该因为重新索引而浪费时间。

无论如何,这是我的代码:

import time
import sys
import numpy as np
import pandas as pd
precision = 6
df = []
for index, i in enumerate(raw):
    if i is None:
        break
    if index%1000 == 0:
        sys.stderr.write('Processed %s...\n' % index)
    df.append(pd.Series(dict([(np.round(mz, precision),int(intensity)) for mz, intensity in i.scans]), dtype='uint16', name=i.rt))

all_indices = set([])
for j in df:
    all_indices |= set(j.index.tolist())

print len(all_indices)
t = time.time()
main_df = pd.DataFrame(index=all_indices)
first = True
del all_indices
while df:
    subset = [df.pop() for i in xrange(10) if df]
    all_indices = set([])
    for j in subset:
        all_indices |= set(j.index.tolist())
    df2 = pd.DataFrame(index=all_indices)
    df2.sort_index(inplace=True, axis=0)
    df2.sort_index(inplace=True, axis=1)
    del all_indices
    ind=0
    while subset:
        t2 = time.time()
        ind+=1
        arr = subset.pop()
        df2[arr.name] = arr
        print ind,time.time()-t,time.time()-t2
    df2.reindex(main_df.index)
    t2 = time.time()
    for i in df2.columns:
        main_df[i] = df2[i]
    if first:
        main_df = main_df.to_sparse()
        first = False
    print 'join time', time.time()-t,time.time()-t2
    print len(df), 'entries remain'

关于如何快速加载这个大型数据集的任何建议都值得赞赏,即使这意味着首先将其写入磁盘到其他格式/等等。

其他一些信息:

1)由于列数,我无法使用大多数传统的磁盘存储,如HDF。

2)数据将在使用时跨列和行进行查询。所以main_df.loc [row:row_end,col:col_end]。这些不是可预测的块大小,因此分块实际上不是一种选择。这些查找也需要很快,大约每秒10次,才能真正有用。

3)我有32G的内存,所以我认为SparseDataFrame是最好的选择,因为它适合内存并允许根据需要快速查找。只是创造它是一种痛苦。

更新

我最终使用scipy稀疏矩阵并暂时处理索引。这导致以~0.2秒的恒定速率附加,这是可接受的(相对于Pandas每次追加我的完整数据集需要约150秒)。我很想知道如何让Pandas与这种速度相匹配。

0 个答案:

没有答案