วิธีที่ง่ายที่สุดคือการใช้map_partitions Dask ของ คุณต้องนำเข้าเหล่านี้ (คุณจะต้องpip install dask
):
import pandas as pd
import dask.dataframe as dd
from dask.multiprocessing import get
และไวยากรณ์คือ
data = <your_pandas_dataframe>
ddata = dd.from_pandas(data, npartitions=30)
def myfunc(x,y,z, ...): return <whatever>
res = ddata.map_partitions(lambda df: df.apply((lambda row: myfunc(*row)), axis=1)).compute(get=get)
(ฉันเชื่อว่า 30 เป็นจำนวนพาร์ติชันที่เหมาะสมหากคุณมี 16 คอร์) เพื่อความสมบูรณ์ฉันกำหนดเวลาความแตกต่างบนเครื่องของฉัน (16 คอร์):
data = pd.DataFrame()
data['col1'] = np.random.normal(size = 1500000)
data['col2'] = np.random.normal(size = 1500000)
ddata = dd.from_pandas(data, npartitions=30)
def myfunc(x,y): return y*(x**2+1)
def apply_myfunc_to_DF(df): return df.apply((lambda row: myfunc(*row)), axis=1)
def pandas_apply(): return apply_myfunc_to_DF(data)
def dask_apply(): return ddata.map_partitions(apply_myfunc_to_DF).compute(get=get)
def vectorized(): return myfunc(data['col1'], data['col2'] )
t_pds = timeit.Timer(lambda: pandas_apply())
print(t_pds.timeit(number=1))
28.16970546543598
t_dsk = timeit.Timer(lambda: dask_apply())
print(t_dsk.timeit(number=1))
2.708152851089835
t_vec = timeit.Timer(lambda: vectorized())
print(t_vec.timeit(number=1))
0.010668013244867325
การให้ปัจจัย 10 speedupจากแพนด้าใช้กับ dask ใช้กับพาร์ติชัน แน่นอนถ้าคุณมีฟังก์ชันที่คุณสามารถ vectorize ได้คุณควร - ในกรณีนี้ function ( y*(x**2+1)
) เป็น vectorized เล็กน้อย แต่มีหลายสิ่งที่เป็นไปไม่ได้ที่จะ vectorize