在python中使用Pandas和Numpy庫創(chuàng)建一個Pandas DataFrame是一個常見的操作,但就是這一個常見的操作也會在特定的場景下遇到問題。
筆者在使用Pandas DataFrame時,遇到了core dump的問題。去掉不相關(guān)的代碼后,基本斷定是如下代碼引起core dump。
import numpy as np
np.random.seed(7)
import pandas as pd
df = pd.DataFrame(np.random.randn(1, 32))
經(jīng)過驗(yàn)證后,發(fā)現(xiàn)只有在column大于31時,會crash。
經(jīng)過搜索資料,發(fā)現(xiàn)原來是Numpy在某些虛擬機(jī)環(huán)境下的bug。具體原因在Numpy的git issue中描述。https://github.com/numpy/numpy/issues/9532
本文作一簡單歸納:
root cause
- 宿主機(jī)CPU并不支持AVX或者AVX2標(biāo)簽,但是在創(chuàng)建虛擬機(jī)時,給系統(tǒng)打上了AVX/AVX2的tag。
- 當(dāng)Pandas創(chuàng)建的DataFrame列大于31時,會走到AVX/AVX2的路徑,因?yàn)樘摂M機(jī)有AVX/AVX2的標(biāo)簽,但是執(zhí)行到AVX/AVX2的邏輯時,因?yàn)樗拗鳈C(jī)并不支持,所以core dump Illegal instruction。
- core棧如下:
Program received signal SIGILL, Illegal instruction.
0xb61338a8 in LONG_greater_avx2 (args=args@entry=0xbfffe52c,
dimensions=dimensions@entry=0xbfffe538, steps=steps@entry=0xbfffe544,
__NPY_UNUSED_TAGGEDfunc=__NPY_UNUSED_TAGGEDfunc@entry=0x0)
at numpy/core/src/umath/loops.c.src:936
936 numpy/core/src/umath/loops.c.src: No such file or directory.
(gdb) bt
#0 0xb61338a8 in LONG_greater_avx2 (args=args@entry=0xbfffe52c,
dimensions=dimensions@entry=0xbfffe538, steps=steps@entry=0xbfffe544,
__NPY_UNUSED_TAGGEDfunc=__NPY_UNUSED_TAGGEDfunc@entry=0x0)
at numpy/core/src/umath/loops.c.src:936
解決方法
- 刪除系統(tǒng)已有的numpy庫
pip uninstall numpy
- 下載numpy源代碼
git clone https://github.com/numpy/numpy.git numpy
-
修改Numpy庫文件 numpy/core/include/numpy/npy_common.h, 將AVX/AVX2 設(shè)為0.code diff
編譯并安裝numpy
python setup.py build
python setup.py install
安裝后在新的shell下重新執(zhí)行python腳本,問題解決。
