【发布时间】:2016-08-27 07:17:54
【问题描述】:
我有两个 csv 文件,我将它们加载到 pandas 数据框中。一个文件很大,大约 10M 行和 20 列(所有字符串类型),大小约为 1G 字节,另一个文件很小,大约 5k 行,5 列,大小约为 1M。我想通过两个数据框之间的单个公共列进行内部连接。
我就是这样加入的,
mergedDataSet = pd.merge(smallDataFrame, largeDataFrame, on='uid', how='inner')
如果我对大数据集的 1% 进行采样,我尝试过,程序运行顺利,没有任何问题,并且在 5 秒内完成,所以我验证了我的代码的功能应该没问题。
但如果我加入真正的大数据集,程序将在大约 20-30 秒后终止,错误消息为Process finished with exit code 137 (interrupted by signal 9: SIGKILL)。我在 Mac OSX 上使用带有 miniconda 的 Python 2.7,我从 PyCharm 运行。我的机器有 16G 内存,远大于 1G 文件的大小。
想知道是否有任何想法来调整 pandas 中数据框连接的性能,或任何其他用于内部连接的快速解决方案?
我的另一个困惑是,为什么程序被杀死了?由谁以及为什么原因?
编辑 1,在进行内部连接时在 /var/log/system.log 中捕获错误,
Aug 27 11:00:18 foo-laptop com.apple.CDScheduler[702]: Thermal pressure state: 1 Memory pressure state: 0
Aug 27 11:00:18 foo-laptop com.apple.CDScheduler[47]: Thermal pressure state: 1 Memory pressure state: 0
Aug 27 11:00:33 foo-laptop iTerm2[43018]: Time to encode state for window <PseudoTerminal: 0x7fb3659d3960 tabs=1 window=<PTYWindow: 0x7fb3637c0c80 frame=NSRect: {{0, 0}, {1280, 800}} title=5. tail alpha=1.000000 isMain=1 isKey=1 isVisible=1 delegate=0x7fb3659d3960>>: 0.02136099338531494
Aug 27 11:00:41 foo-laptop iTerm2[43018]: Time to encode state for window <PseudoTerminal: 0x7fb3659d3960 tabs=1 window=<PTYWindow: 0x7fb3637c0c80 frame=NSRect: {{0, 0}, {1280, 800}} title=5. tail alpha=1.000000 isMain=0 isKey=0 isVisible=1 delegate=0x7fb3659d3960>>: 0.01138699054718018
Aug 27 11:00:46 foo-laptop kernel[0]: low swap: killing pid 92118 (python2.7)
Aug 27 11:00:46 foo-laptop kernel[0]: memorystatus_thread: idle exiting pid 789 [CallHistoryPlugi]
Aug 27 11:00:56 foo-laptop iTerm2[43018]: Time to encode state for window <PseudoTerminal: 0x7fb3659d3960 tabs=1 window=<PTYWindow: 0x7fb3637c0c80 frame=NSRect: {{0, 0}, {1280, 800}} title=5. tail alpha=1.000000 isMain=0 isKey=0 isVisible=1 delegate=0x7fb3659d3960>>: 0.01823097467422485
Aug 27 11:00:58 foo-laptop kernel[0]: process WeChat[85077] caught causing excessive wakeups. Observed wakeups rate (per sec): 184; Maximum permitted wakeups rate (per sec): 150; Observation period: 300 seconds; Task lifetime number of wakeups: 2193951
Aug 27 11:00:58 foo-laptop com.apple.xpc.launchd[1] (com.apple.ReportCrash[92123]): Endpoint has been activated through legacy launch(3) APIs. Please switch to XPC or bootstrap_check_in(): com.apple.ReportCrash
Aug 27 11:00:58 foo-laptop ReportCrash[92123]: Invoking spindump for pid=85077 wakeups_rate=184 duration=245 because of excessive wakeups
Aug 27 11:01:03 foo-laptop com.apple.CDScheduler[702]: Thermal pressure state: 0 Memory pressure state: 0
Aug 27 11:01:03 foo-laptop com.apple.CDScheduler[47]: Thermal pressure state: 0 Memory pressure state: 0
问候, 林
【问题讨论】:
-
也许 'uid' 列中的值是多对多的,例如对于值 1,您在第 1 帧中获得 100 条记录,在第 2 帧中获得 10 条记录,因此连接会产生 1000 条记录。可能发生的情况是您的框架变得如此之大,以至于无法放入内存或占用所有资源。
-
我同意 @AndreyVykhodtsev - 如果您在
uid列中有重复项 - 它们将在合并的 DF 中相乘(例如,如果您有 3xuids 值1合二为一DF 和 2xuids 在第二个 DF 中的值为1- 在合并的 DF 中您将有 6 行 和uid==1)。很可能您的 Python 进程被 OOM(内存不足)杀手杀死 - 检查/var/log/system.log(/var/log/messages) -
是的,只要检查两边的 df['uid'].value_counts() 即可。或 df1[df1.uid.isin(df2.uid.unique())]['uid'].value_counts()
-
@AndreyVykhodtsev,看来您的猜测是正确的。您介意添加回复,以便我可以将其标记为答案以造福他人吗?顺便说一句,你能解释一下这句话是什么意思
df1[df1.uid.isin(df2.uid.unique())]['uid'].value_counts(),被isin(df2.uid.unique())]部分弄糊涂了。 -
@AndreyVykhodtsev,我同意 Lin Ma - 如果您将其作为答案发布(最好是一个小例子),它可能会帮助其他人;)
标签: python performance python-2.7 pandas dataframe