2016-10-03 134 views
0

我有两只大熊猫DataFrames df1df2用相当标准的格式:大熊猫上的外部合并DataFrames导致MemoryError ---如何将“大数据”与大熊猫合并?

one two three feature 
A 1 2  3 feature1 
B 4 5  6 feature2 
C 7 8  9 feature3 
D 10 11  12 feature4 
E 13 14  15 feature5 
F 16 17  18 feature6 
... 

并为df2相同的格式。这些数据帧的大小大约为175MB和140MB。

merged_df = pd.merge(df1, df2, on='feature', how='outer', suffixes=('','_features')) 

我得到以下的MemoryError:

File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 39, in merge 
    return op.get_result() 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 217, in get_result 
    join_index, left_indexer, right_indexer = self._get_join_info() 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 353, in _get_join_info 
    sort=self.sort, how=self.how) 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 559, in _get_join_indexers 
    return join_func(lkey, rkey, count, **kwargs) 
File "pandas/src/join.pyx", line 187, in pandas.algos.full_outer_join (pandas/algos.c:61680) 
    File "pandas/src/join.pyx", line 196, in pandas.algos._get_result_indexer (pandas/algos.c:61978) 
MemoryError 

是否有可能有一个 “大小限制” 大熊猫dataframes合并是什么时候?我很惊讶,这是行不通的。也许这是某个熊猫版本的错误?

编辑:正如在评论中提到的,合并列中的许多重复项可能很容易导致RAM问题。参见:Python Pandas Merge Causing Memory Overflow

现在的问题是,我们该如何做到这一点合并?不知何故,最好的办法是分割数据框。

+0

在'feature'列中是否有重复内容?如果有很多重复项,你的连接最终会变成**非常大** – maxymoo

+0

@maxymoo是的。你能解释为什么这会超过内存限制吗?假设'df1'有1000万行,特征1有500K行,特征2有500K行等等。数据帧本身只有150 MB ---为什么会出现内存错误? – ShanZhengYang

+0

你使用的是32位的python/64位? –

回答

1

您可以尝试第一个过滤器df1通过unique值,merge和最后concat输出。

如果只需要外连接,我觉得还有内存问题。但是,如果为每个循环的过滤器输出添加一些其他代码,它可以工作。

dfs = [] 
for val in df.feature.unique(): 
    df1 = pd.merge(df[df.feature==val], df2, on='feature', how='outer', suffixes=('','_key')) 
    #http://stackoverflow.com/a/39786538/2901002 
    #df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
    print (df1) 
    dfs.append(df1) 

df = pd.concat(dfs, ignore_index=True) 
print (df) 

其他的解决方案是使用dask.dataframe.DataFrame.merge

1

尝试指定一个数据类型的数字列,以减少现有的数据帧的大小,如:

df[['one','two', 'three']] = df[['one','two', 'three']].astype(np.int32) 

这应该显著减少内存,并希望让你瓶坯合并。

+0

我猜这可能对于非常大的连接没有太大帮助,如上所述。有没有一种有效的方法来通过独特的“特征”来分割数据框?如果有(比方说)具有100 MB数据帧的10个功能,您可能会获得更小的数据帧(如果统一,每个大约10 MB) – ShanZhengYang

+0

我不确定是否有效地按照您的方式拆分数据帧暗示,但它可能会删除在两个初始数据框之间共享的所有列。目标是外连接,因此移除对数据框不唯一的列不会影响结果,但会减少内存。就像@jezrael刚刚发布的答案一样。 –