【发布时间】:2015-06-30 15:56:21
【问题描述】:
我尝试将大约 30 GB 的数据(在大约 900 个数据帧的列表中)连接在一起。我正在使用的机器是一个功能适中的 Linux Box,内存约为 256 GB。但是,当我尝试连接我的文件时,我很快就用完了可用的内存。我已经尝试了各种解决方法来解决这个问题(用 for 循环等小批量连接),但我仍然无法将它们连接起来。两个问题浮现在脑海:
有没有其他人处理过这个问题并找到了有效的解决方法?我不能使用直接追加,因为我需要
pd.concat()中的join='outer'参数的“列合并”(因为缺少更好的词)功能。为什么 Pandas 连接(我知道它只是调用
numpy.concatenate)对内存的使用效率如此之低?
我还应该注意,我认为问题不是列的爆炸,因为将 100 个数据帧连接在一起会产生大约 3000 个列,而基本数据帧大约有 1000 个。
编辑:
我正在处理的数据是我的 900 个数据帧中的每一个数据帧大约 1000 列宽和大约 50,000 行深的财务数据。从左到右的数据类型有:
- 字符串格式的日期,
stringnp.floatint
... 以此类推。我将列名与外部连接连接起来,这意味着df2 中不在df1 中的任何列都不会被丢弃,而是被分流到一边。
示例:
#example code
data=pd.concat(datalist4, join="outer", axis=0, ignore_index=True)
#two example dataframes (about 90% of the column names should be in common
#between the two dataframes, the unnamed columns, etc are not a significant
#number of the columns)
print datalist4[0].head()
800_1 800_2 800_3 800_4 900_1 900_2 0 2014-08-06 09:00:00 BEST_BID 1117.1 103 2014-08-06 09:00:00 BEST_BID
1 2014-08-06 09:00:00 BEST_ASK 1120.0 103 2014-08-06 09:00:00 BEST_ASK
2 2014-08-06 09:00:00 BEST_BID 1106.9 11 2014-08-06 09:00:00 BEST_BID
3 2014-08-06 09:00:00 BEST_ASK 1125.8 62 2014-08-06 09:00:00 BEST_ASK
4 2014-08-06 09:00:00 BEST_BID 1117.1 103 2014-08-06 09:00:00 BEST_BID
900_3 900_4 1000_1 1000_2 ... 2400_4 0 1017.2 103 2014-08-06 09:00:00 BEST_BID ... NaN
1 1020.1 103 2014-08-06 09:00:00 BEST_ASK ... NaN
2 1004.3 11 2014-08-06 09:00:00 BEST_BID ... NaN
3 1022.9 11 2014-08-06 09:00:00 BEST_ASK ... NaN
4 1006.7 10 2014-08-06 09:00:00 BEST_BID ... NaN
_1 _2 _3 _4 _1.1 _2.1 _3.1 _4.1 0 #N/A Invalid Security NaN NaN NaN #N/A Invalid Security NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN
dater
0 2014.8.6
1 2014.8.6
2 2014.8.6
3 2014.8.6
4 2014.8.6
[5 rows x 777 columns]
print datalist4[1].head()
150_1 150_2 150_3 150_4 200_1 200_2 0 2013-12-04 09:00:00 BEST_BID 1639.6 30 2013-12-04 09:00:00 BEST_ASK
1 2013-12-04 09:00:00 BEST_ASK 1641.8 133 2013-12-04 09:00:08 BEST_BID
2 2013-12-04 09:00:01 BEST_BID 1639.5 30 2013-12-04 09:00:08 BEST_ASK
3 2013-12-04 09:00:05 BEST_BID 1639.4 30 2013-12-04 09:00:08 BEST_ASK
4 2013-12-04 09:00:08 BEST_BID 1639.3 133 2013-12-04 09:00:08 BEST_BID
200_3 200_4 250_1 250_2 ... 2500_1 0 1591.9 133 2013-12-04 09:00:00 BEST_BID ... 2013-12-04 10:29:41
1 1589.4 30 2013-12-04 09:00:00 BEST_ASK ... 2013-12-04 11:59:22
2 1591.6 103 2013-12-04 09:00:01 BEST_BID ... 2013-12-04 11:59:23
3 1591.6 133 2013-12-04 09:00:04 BEST_BID ... 2013-12-04 11:59:26
4 1589.4 133 2013-12-04 09:00:07 BEST_BID ... 2013-12-04 11:59:29
2500_2 2500_3 2500_4 Unnamed: 844_1 Unnamed: 844_2 0 BEST_ASK 0.35 50 #N/A Invalid Security NaN
1 BEST_ASK 0.35 11 NaN NaN
2 BEST_ASK 0.40 11 NaN NaN
3 BEST_ASK 0.45 11 NaN NaN
4 BEST_ASK 0.50 21 NaN NaN
Unnamed: 844_3 Unnamed: 844_4 Unnamed: 848_1 dater
0 NaN NaN #N/A Invalid Security 2013.12.4
1 NaN NaN NaN 2013.12.4
2 NaN NaN NaN 2013.12.4
3 NaN NaN NaN 2013.12.4
4 NaN NaN NaN 2013.12.4
[5 rows x 850 columns]
【问题讨论】:
-
您能否提供更多信息:行数、每个数据帧的列数。每个字段的类型是什么。你正在加入什么。
-
@sfortney 如果您可以添加一个小的、完整的、可运行的示例来展示您的代码是如何工作的,那将会有所帮助。然后我们都会在同一个页面上。您可以手动编码或随机生成三个或四个小的 DataFrame,并以代码的形式准确显示您是如何连接它们的。有关类似示例,请参阅此最近的问题:stackoverflow.com/q/29629821/553404
-
一般来说,顺序连接子数组是生成单个大数组的慢速方法。连接
a和b涉及分配一个新的输出数组,其大小为a和b的总和。随着您的输出数组变得越来越长,分配每个新数组的成本也越来越大。最好预先分配一个与整个输出数组大小相同的数组,然后在执行过程中填充行。 -
是的 - 请参阅 StringBuilder 类的类似案例yoda.arachsys.com/csharp/stringbuilder.html
-
另一个 pandas 特有的点 - 你肯定希望将
copy=False传递给pd.concat()以避免生成不必要的副本