close menu

וגם: אז מה זה הPolars הזה שכולם מדברים עליו פתאום?

אז כמו כולם בתחום, החלטתם לחזות מחירי בתים בבוסטון..

או סרטן השד, או מי מת בטיטאניק, או איכות יין, או איריס (שעד עכשיו אין לי מושג מה עושים בדאטהסט הזה למרות שהגעתי בו ל1.0)

..וכמו שצריך לעשות: החלטתם להנדס קצת פיצ'רים!

הגעתם למסקנה שמאפיין די ברור המשפיע על המחיר יהיה כמובן "עד כמה גודל הדירה חריג ביחס לשאר הדירות בשכונה" כמובן.

פתחתם את הקוד, כתבתם את הGroupBy ויצאתם הביתה..

..רק כדי לחזור ביום למחרת בדיוק לאותו המסך ממקודם שעדיין מחשב את הGroupBy.

עד מתי פנדס?

כך תאיצו את החישובים על הדאטה שלכם – שיטות פופולריות (עם קוד לדוגמה)

אבל עכשיו כשאתם מקשיבים, דעתי שלא ביקשתם לשמוע:

לפני שאתחיל, אשמח לשתף אתכם בדעתי המאוד לא פופולרית בתחום: בסבירות גבוהה מאוד, אתם לא צריכים שום דבר ממה שכתוב כאן.

אני אישית עובד עם פנדס נקי גם על דאטהסטים בגודל מאות ג'יגהבייטים בלי בעיה.

זה תופס גם למהירות של פייתון: כמעט תמיד כשאנשים אומרים שפייתון לא מספיק מהירה ולכן שוקלים לעבור לשפות אחרות: מדובר בצוואר בקבוק בקוד ולא בשפה עצמה. פרופיילינג פשוט למדידת מהירות חלקים שונים בקוד בסבירות גבוהה יפתור את הבעיה שלכם (בעשר דקות עבודה במקרים רבים). לא רק שפייתון מספיק מהירה כמעט להכל, בגרסאות החדשות: פייתון עברה האצת ביצועים משמעותית! נסו!

לכל היותר, אני ממליץ לכם להשתמש במולטי-פרוססינג (עוד רגע סינטקס) ובמקרים באמת חריגים שמהירות חשובה במיוחד נסו את Numba (המצריכה בדרך כלל שינויים מזעריים לקוד הקיים אם אתם לא עושים שום דבר מיוחד מידי).

כמו בכל שאר הדברים שאתם עושים ביום יום, תמיד חשוב לזכור: הזמן שלכם הוא הזמן היקר ביותר.

בפער משמעותי יותר משל המחשב (או הקלאסטר בענן).

זמן שאתם מקדישים ללמידה של ספריה אחרת או לתרגום קוד לספריה אחרת יקר ב-מ-י-ו-ח-ד ועליכם להתייחס אליו כך.

וזה עוד לפני שהזכרנו את חבריכם המסכנים לצוות שאתם מייצרים להם עבודה: ספריות אחרות מוסיפות גם לשאר חברי הצוות שלכם זמן לימוד על מנת שיוכלו להכנס אל הקוד שלכם.

עם זאת, יש גם צד שני: האצת חישובים כן צריכה להיות במקום גבוה מאוד בסדר העדיפויות שלכם, חישובים מהירים מאפשרים לכם לבצע יותר ניסויים (בדרך כלל בלי שתרגישו) ויותר ניסויים בצעדים קטנים זו הדרך הטובה ביותר (בדרך כלל) למטרות שלכם בפרוייקטים בתחום.

כך תאיצו את החישובים שלכם – חבילות

קודם כל בלי חבילה – הכי פשוט:

לפני שנבדוק חבילות מיוחדות, למי שלא מכיר: import multiprocessing של פייתון.

חבילה זו מאפשרת לכם להריץ קוד פשוט על מספר מעבדים\ליבות\ת'רדים במקביל כשהדרך הפשוטה ביותר היא על ידי multiprocessing.pool.Pool המאפשר לכם להריץ map פשוט רק מבוזר: for result in pool.map(task, items) יריץ את הפונקציה task על כל אחד מהאיברים בitems כאשר הריצות מתבצעות במקביל על מספר המעבדים שיש לכם גישה אליהם.

רק שימו לב, בשימוש "כל כך פשוט" אתם מעתיקים את הדאטה כמספר המעבדים ולכן שימו לב למשאבי החישוב העומדים לרשותכם במחשב עליו אתם פועלים ולגודל הדאטה איתו אתם עובדים.

הוספת מקביליות לפנדס – pandas-parallel

הכירו את pip install pandas-parallel

חבילה זו שמה לעצמה מטרה אחת: לא לשנות כלום.

שימוש בחבילה זו מאפשר לכם לבצע ה-כ-ל אותו הדבר כשהיא מבזרת בשבילכם את החישובים על מספר מעבדים ברקע.

בניגוד לחבילה הבאה עליה נדבר, חבילה זו אינה "תחליף לפנדס". היא רק מוסיפה לה פונקציונליות כך שאתם לא לוקחים סיכון ש"משהו רנדומלי ישבר" כשאתם משתמשים בה. מומלץ!

החלפת פנדס בגרסה מקבילית – modin:

ממשיכים בגישת ה"אפס שינויים", הכירו את modin – חבילה שמטרתה "להחליף" את פנדס בלי שתרגישו.

השימוש בה הוא import modin.pandas as pd ומומלץ "פשוט לנסות" במידה ואתם נתקלים בבעיות מהירות.

בונוס: החבילה גם טוענת קבצי csv מהר יותר מפנדס בצורה מקבילית.

להריץ על הGPU – עם CuDF מהחבילה RAPIDS של אנבידיה:

השיטה המהירה ביותר (בדרך כלל) היא שימוש בRAPIDS של אנבידיה – החבילה (מן הסתם) משתמשת בGPU ומבצעת בדיוק את אותם החישובים באותו הסינטקס לו אתם מצפים מפנדס.

חסרון שאי אפשר להתעלם ממנו: ישנם חישובים כאלו ואחרים שהחבילה אינה תומכת בהם "מהקופסה". חישובים אלו בדרך כלל איתם החישובים הנפוצים ביותר ולא תמיד נתקלים בהם. מומלץ לבדוק ולראות בעצמכם.

חסרון נוסף שקשה להתעלם ממנו: במידה ואתם לא משתמשים בדוקר הרשמי של אנבידיה, קשה מאוד להתקין את RAPIDS.

פתרונות מקביליות על מספר מכונות – Dask ,Ray Spark

גם DASK גם Spark וגם RAY הם פתרונות מקביליות המציעים ביזור גם על מספר מכונות. לא אכנס אליהם בפוסט זה, דעתי האישית היא שאם הגעתם למצב בו אתם שוקלים אותם: בבקשה חשבו שוב.

חוץ ממקרים חריגים: כנראה שגודל הדאטה שלכם לא באמת כל כך גדול.

אפשר לעבוד עם פתרונות הרבה יותר פשוטים על מכונה בודדת.

הספריה החדשה – Polars:

כולם מדברים על הספריה החדשה: Polars.

מה זו הספריה הזו, והאם יש סיבה לבדוק אותה?

על פי המדריך למשתמש מטרת הספריה "לספק ספריית DataFrame במהירות גבוהה המשתמשת בכל הליבות הזמינות".

בניגוד לספריות אחרות כמו Dask הבנויות מעל פנדס ומנסות למקבל אותה, ספריה זו נבנתה מהיסוד (בRust) ומאפשרת גישה אליה דרך פייתון. היא אינה "פנדס" בשום צורה.

התקנה וממשק פשוט:

התקנת הספריה פשוטה במיוחד: pip install polars

וממשק הספריה הפשוט ביותר מזכיר את פנדס, להלן מספר דוגמאות:

קריאה – אותו הדבר:

  • df = pl.read_csv(..)

פונ' בסיסיות – אותו הדבר:

  • df.head()
  • df.tail()
  • df.unique()

כל אלו עובדים גם בpolars וחלקם בהחלט מהירים יותר.

גישה לעמודות ספציפיות:

  • # Pandas
  • df[['col1', 'col2']]
  • # Polars
  • df.select(pl.col(['col1', 'col2']))

גישה זו למשל בפנדס לוקחת פי 15 יותר זמן.

כנ"ל לגבי חיתוך הדאטה:

  • # Pandas
  • df.query('col1 > 5')
  • # Polars
  • df.filter(pl.col('col') > 5)

אך יצירת עמודות חדשות איטית יותר בPolars ומתבצעת כך:

  • # Pandas
  • df_pd["new_col"] = df_pd["col"] * 10
  • # Polars
  • df.with_columns([(pl.col("col") * 10).alias("new_col")])

שימוש בGroupBy ואגרגציה:

# Pandas

df_pd.groupby('col1')['col2'].agg('mean')

# Polars

df.groupby('col1').agg([pl.mean('col2')])

מהיר בערך פי 2 בPolars

טיפול בערכים חסרים:

  • # Pandas
  • df['col2'].fillna(-999)
  • # Polars
  • df_pd.with_column(pl.col('col2').fill_null(-999))

הבדל מעניין: ממשק Eager וממשק Lazy:

לספריה שני ממשקי משתמש עיקריים, ממשק eager בו החישובים פועלים מיד וממשק lazy בו החישובים מבוצעים רק לאחר שהוגדרו.

על מנת להשתמש בממשק בlazy יש להשתמש בפונ' lazy ולאחריה לקרוא לפונקציה collect.

דוגמה:

  • df.lazy()
  • .with_columns([(pl.col("col") * 10).alias("new_col")])
  • #…
  • .collect()

כמו שאתם מדמיינים, ניתן לייצא גם גרף חישוב ממשק הLazy.

סיכום קצר לגבי Polars:

אמנם לא הרצתי יותר מידי ניסויים אך נראה כי החבילה בהחלט מהירה יותר בחלק גדול מהפעולות. אך כמו כן היא מצריכה שינוי יחסית רציני לקוד הקיים והיתי שוקל אותה רק במקרים חריגים במיוחד.

שכל אחד יעשה את שיקוליו בנוגע אליה.

עוד בנושא: