ספריית pandas - חלק 3 - מבני נתונים - DataFrame - חלק ב

Image result for pandas logo

הוספת עמודות על בסיס עמודות אחרות - פונקציית assign

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

>>> df = pd.DataFrame({'a':np.arange(1,5),'b':np.arange(10,50,10),
                       'c':np.arange(100,500,100)})
>>> df
   a   b    c
0  1  10  100
1  2  20  200
2  3  30  300
3  4  40  400

>>> df.assign(d = df['a'] + df['b'])
   a   b    c   d
0  1  10  100  11
1  2  20  200  22
2  3  30  300  33
3  4  40  400  44

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

>>> df.assign(e = lambda x: x['c'] / x['b'] )
   a   b    c     e
0  1  10  100  10.0
1  2  20  200  10.0
2  3  30  300  10.0
3  4  40  400  10.0

בדוגמה הזו x הוא df.
הצורה הזו שימושית במקרה שאין לנו אפשרות לגשת ישירות ל-df למשל כשמשרשרים פקודות.

>>> df.query('a > 2').assign(f = lambda x: x.a * a.b) 
   a   b    c   f
2  3  30  300  12
3  4  40  400  16

בדוגמה הזו ע"י פונקציית query מקבלים df חדש שמכיל רק את השורות שבהם a>2 ועל ה-df החדש הזה יוצרים את עמודה f עם פונקציה פנימית בתוך ה-assign. ה-x בפונקציה הפנימית מייצג את ה-df החדש.

החל מגירסה 0.23.0 (פייתון 3.6) ניתן להתייחס באותו assign לעמודות חדשות שנוצרו באותה הפקודה לפני העמודה הנוכחית, לדוגמה:


>>> df = pd.DataFrame({'a':[1,2,3],
                       'b':[3,4,5]})
>>> df
   a  b
0  1  3
1  2  4
2  3  5

>>> df.assign(c = lambda x: x['a'] + x['b'],
              d = lambda x: x['c'] + x['a'])
   a  b  c   d
0  1  3  4   5
1  2  4  6   8
2  3  5  8  11

כשעמודה d נוצרת היא מסתמכת על עמודה c שנוצרה ממש לפניה באותה פקודת assign.

אינדוקס ובחירת חתך מ-DataFrame


קריאת עמודה

df[col] --> return Series
קריאת שורה ע"י תוית
df.loc[label] --> return Series
קריאת שורה ע"י מיקום
df.iloc[col] --> return Series
קריאת טווח שורות
df[5:10] --> return DataFrame
קריאת שורות ע"י וקטור בוליאני
df[bool_vec] --> return DataFrame

כשקוראים שורה, האינדקסים שלה הם שמות העמודות של ה-df.
לדוגמה:


>>> df = pd.DataFrame({'red':[1,2,3],
                       'blue':[3,4,5],
                       'green':[6,7,8]},index=['a','b','c'])
>>> df
   red  blue  green
a    1     3      6
b    2     4      7
c    3     5      8

>>> df.loc['a']
red      1
blue     3
green    6
Name: a, dtype: int64

>>> df.iloc[1]
red      2
blue     4
green    7
Name: b, dtype: int64


פעולות אריתמטיות ובוליניות

פעולות אריתמטיות עם סקלר יתבצעו על כל האיברים:

>>> df1
   red  blue  green
a    1     4      7
b    2     5      8
c    3     6      9

>>> df1 + 2
   red  blue  green
a    3     6      9
b    4     7     10
c    5     8     11

>>> df1 * 5 
   red  blue  green
a    5    20     35
b   10    25     40
c   15    30     45

פעולות בוליניות גם הם יתבצעו בצורה אינטואיטיבית.
הפעולות הבוליניות הן:
or  --> |
and --> &
xor --> ^
not --> -
לדוגמה:

>>> df1 = pd.DataFrame({'a': [1, 0, 1], 'b': [0, 1, 1]}, dtype = bool)

>>> df2 = pd.DataFrame({'a': [1, 1, 0], 'b': [0, 1, 0]}, dtype = bool)

>>> df1
       a      b
0   True  False
1  False   True
2   True   True

>>> df2
       a      b
0   True  False
1   True   True
2  False  False

>>> df1 | df2
      a      b
0  True  False
1  True   True
2  True   True

>>> -df1
       a      b
0  False   True
1   True  False
2  False  False

היפוך (transpose) של DataFrame

הפיכה של DataFrame כך שהשורות יהיו העמודות ולהפך מתבצעת בדומה ל-np.ndarray פשוט ע"י T:

>>> df1 = pd.DataFrame({'red':[1,2,3],
                        'blue':[4,5,6],
                        'green':[7,8,9]},index=['a','b','c'])

>>> df1
   red  blue  green
a    1     4      7
b    2     5      8
c    3     6      9

>>> df1.T
       a  b  c
red    1  2  3
blue   4  5  6
green  7  8  9


Data alignment

בדומה ל-label alignment שהסברנו על Series בחלק 1 גם בפעולות בין df שונים יש data alignment. ההתאמה מתבצעת לפי עמודות ואינדקסים (שורות) והתוצאה תהיה איחוד של העמודות והאינדקסים הזהים.
לדוגמה:

>>> df1 = pd.DataFrame({'red':[1,2,3],
                        'blue':[4,5,6],
                        'green':[7,8,9]},index=['a','b','c'])
>>> df2 = pd.DataFrame({'red':[10,20,30],
                        'blue':[40,50,60],
                        'yellow':[70,80,90]},index=['d','c','b'])

>>> df1
   red  blue  green
a    1     4      7
b    2     5      8
c    3     6      9

>>> df2
   red  blue  yellow
d   10    40      70
c   20    50      80
b   30    60      90

>>> df1 + df2
   blue  green   red  yellow
a   NaN    NaN   NaN     NaN
b  65.0    NaN  32.0     NaN
c  56.0    NaN  23.0     NaN
d   NaN    NaN   NaN     NaN

בפעולה בין df ל-Series ה-alignment יהיה בין האינדקסים של ה-Series לעמודות של ה-df  ויתבצע broadcasting של ה-Series על פני כל השורות של ה-df.
לדוגמה:

>>> df1
   red  blue  green
a    1     4      7
b    2     5      8
c    3     6      9

>>> df1.iloc[1] # this is Series

red      2
blue     5
green    8
Name: b, dtype: int64

>>> df1 - df1.iloc[1]
   red  blue  green
a   -1    -1     -1
b    0     0      0
c    1     1      1

ביצוע פונקציות NumPy על DataFrame ו-Series

פונקציות NumPy שמתבצעות פר אלמנט ניתן להשתמש ישירות על df או Series.
לדוגמא:

>>> np.exp(df)
>>> np.sin(df)

וכן פונקציות NumPy רבות נוספות:

>>> np.max(df)
>>> np.mean(df)
>>> np.median(df)

פונקציות שפועלות על שני אובייקטים למשל שני Series, יבצעו קודם כל label alignment ואז יבצעו את הפונקציה. למשל הפונקציה np.remainder שמחלקת מערך אחד בשני ומחזירה שארית של כל תא תבצע קודם alignment:

>>> a = pd.Series([10,3,5], index=['a','b','c'])
>>> b = pd.Series([1,2,7], index=['c','b','a'])
>>> np.remainder(a,b)
a    3
b    1
c    0
dtype: int64


עד כאן להפעם. בהצלחה.

אם אהבתם, תכתבו משהו למטה...

אין תגובות:

הוסף רשומת תגובה