Bài 23: GroupBy (Nhóm dữ liệu) - p1 - Python Panda

Đăng bởi: Admin | Lượt xem: 5409 | Chuyên mục: Python


Với "groupby " chúng ta đang đề cập đến một quá trình liên quan đến một hoặc nhiều bước sau:
        (1) Chia dữ liệu thành các nhóm dựa trên một số tiêu chí
        (2) Áp dụng một số tính toán cho từng nhóm một cách độc lập
        (3) Kết hợp các kết quả vào một cấu trúc dữ liệu
Trong số này, bước phân chia nhóm (1) là đơn giản nhất. Trên thực tế, trong nhiều trường hợp, bạn có thể chia tập dữ liệu thành các nhóm và làm điều gì đó với các nhóm đó. Trong bước (2), mong muốn có thể là một trong những điều sau:
        Tổng hợp (Aggregation/Reduction): phân tích thống kê trong một nhóm. Ví dụ:
                Tính sum, mean, std, min, max của nhóm dữ liệu
                Tính toán số lượng nhóm (size/count)
        Chuyển đổi (Transformation): thực hiện một số tính toán nhóm cụ thể và trả về một kiểu giống chỉ mục. Vài ví dụ:
                Chuẩn hoá dữ liệu (zscore) trong nhóm
                Fill các giá trị NAs  bằng  một giá trị từ các nhóm.
        Lọc (Filtration): loại bỏ một số nhóm, tính toán theo nhóm nhằm đánh giá Đúng hay Sai. Vài ví dụ:
                Loại bỏ dữ liệu thuộc nhóm chỉ với một vài thành viên
                Lọc dữ liệu dựa trên sum hay mean của nhóm
        Hoặc là kết hợp của các điều trên: GroupBy sẽ kiểm tra kết quả của các bước và cố gắng trả lại một kết quả hợp lý hợp lý nếu nó không phù hợp với một trong hai loại trên.
Bài học gồm:
            + groupdby
            + Tổng hợp (Aggregation/Reduction)
Cú pháp trong pandas tự nhiên hơn cách làm trong sql.
Chẳng hạn trong sql, groupby như sau.
SELECT Column1, Column2, mean(Column3), sum(Column4)
FROM SomeTable
GROUP BY Column1, Column2
Ví dụ, groupby trong dataframe.
>>> import pandas as pd

>>> import numpy as np
>>> df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar'],'B' : ['one', 'one', 'two', 'three'],'C' : np.random.randn(4), 'D' : np.random.randn(4)})
>>> df
     A      B         C         D
0  foo    one  0.064892  1.436126
1  bar    one  1.119634 -1.452583
2  foo    two  0.369738  1.437522
3  bar  three  0.114924  0.849737
>>> grouped = df.groupby(['A', 'B'])
>>> grouped.last()
                  C         D
A   B
bar one    1.119634 -1.452583
    three  0.114924  0.849737
foo one    0.064892  1.436126
    two    0.369738  1.437522
>>> grouped.count()
           C  D
A   B
bar one    1  1
    three  1  1
foo one    1  1
    two    1  1
>>> grouped.sum()
                  C         D
A   B
bar one    1.119634 -1.452583
    three  0.114924  0.849737
foo one    0.064892  1.436126
    two    0.369738  1.437522
>>>
TRICK. Chú ý với kiểu dữ liệu string (categorical data) ở cột A và cột B. Ta cần chuyển A và B về kiểu category type để có được những lợi ích sau: Tốn ít bộ nhớ, tăng tốc các operations đặc biệt là trong groupby().
>>> df.A.unique()

array(['foo', 'bar'], dtype=object)

>>> df.B.unique()

array(['one', 'two', 'three'], dtype=object)

>>> df.A = df.A.astype('category')

>>> df.B = df.B.astype('category')
Ví dụ, groupby trong Series
>>> s = pd.Series(list(df['C']), df['A'])

>>> s

A

foo    0.064892

bar    1.119634

foo    0.369738

bar    0.114924

dtype: float64

>>> grouped = s.groupby(level=0)

>>> grouped.first()

A

bar    1.119634

foo    0.064892

dtype: float64

>>> grouped.count()

A

bar    2

foo    2

dtype: int64

>>> grouped.sum()

A

bar    1.234558

foo    0.434630

dtype: float64

>>>
Theo mặc định, các keys được sắp xếp trong quá trình groupby. Tuy nhiên bạn có thể không sắp xếp qua phép gán sort = False để tăng tốc:
>>> df.groupby(['A','B']).sum()

                  C         D

A   B

bar one    1.119634 -1.452583

    three  0.114924  0.849737

foo one    0.064892  1.436126

    two    0.369738  1.437522

>>> df.groupby(['A','B'],sort=False).sum()

                  C         D

A   B

foo one    0.064892  1.436126

bar one    1.119634 -1.452583

foo two    0.369738  1.437522

bar three  0.114924  0.849737

>>>
Ta có thể nhận kết quả của groupby là kiểu dictionary qua thuộc tính “groups”
>>> df.groupby('A').groups

{'foo': Int64Index([0, 2], dtype='int64'), 'bar': Int64Index([1, 3], dtype='int64')}

>>>
Duyệt qua toàn bộ grouped
>>> grouped = df.groupby(['A','B'])

>>> for name, group in grouped:

...     print name

...     print group

...

('bar', 'one')

     A    B         C         D

1  bar  one  1.119634 -1.452583

('bar', 'three')

     A      B         C         D

3  bar  three  0.114924  0.849737

('foo', 'one')

     A    B         C         D

0  foo  one  0.064892  1.436126

('foo', 'two')

     A    B         C         D

2  foo  two  0.369738  1.437522

>>>
Phương thức get_group() giúp ta có được giá trị của một nhóm. Ví dụ
>>> grouped.get_group(('foo','two'),None)

     A    B         C         D

2  foo  two  0.369738  1.437522

>>>
Aggregation
Các phép “aggregation/reduction” có sẵn như sum(), count(),mean() ngoài ra ta có thể tự định nghĩa nhiều “aggregation” riêng cho dữ liệu của mình.
Tạo một dataframe để minh họa cho bài học.
>>> import pandas as pd

>>> import numpy as np

>>> df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar'],'B' : ['one', 'one', 'two', 'three'],'C' : np.random.randn(4), 'D' : np.random.randn(4)})

>>> df

     A      B         C         D

0  foo    one  0.791518 -0.184029

1  bar    one  0.268664 -0.891467

2  foo    two  0.652872  1.045733

3  bar  three  0.650932 -1.657792

>>>
Ví dụ sau: so sánh kết quả của “aggregate” sử dụng hàm có sắn np.sum và một hàm tự viết để tính tổng trong một group.
>>> grouped.aggregate(np.sum)

                  C         D

A   B

bar one   -0.312775  0.873260

    three -0.229364 -0.177659

foo one   -1.270082 -1.648492

    two   -0.605489  0.885898
Một ví dụ cho việc sử dụng custom aggregation.
>>> grouped.aggregate(lambda series: reduce(lambda x, y: x + y, series.tolist()))

                  C         D

A   B

bar one   -0.312775  0.873260

    three -0.229364 -0.177659

foo one   -1.270082 -1.648492

    two   -0.605489  0.885898

>>>
Trong quá trình “aggregation” ta có thể áp dụng cùng lúc nhiều hàm.
>>> grouped['C'].aggregate([np.sum, np.mean, np.std])

                sum      mean  std

A   B

bar one   -0.312775 -0.312775  NaN

    three -0.229364 -0.229364  NaN

foo one   -1.270082 -1.270082  NaN

    two   -0.605489 -0.605489  NaN

>>>
Ta có thể áp dụng từng hàm cho từng cột trong quá trình “aggregation”
>>> grouped.agg({'C' : np.sum,'D' : np.mean})

                  C         D

A   B

bar one   -0.312775  0.873260

    three -0.229364 -0.177659

foo one   -1.270082 -1.648492

    two   -0.605489  0.885898

>>>
Bài tiếp theo: GroupBy (Nhóm dữ liệu)- P2 >>
vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!