Hãy xem xét các khung dữ liệu sau:
A B C D
0 foo one 0.162003 0.087469
1 bar one -1.156319 -1.526272
2 foo two 0.833892 -1.666304
3 bar three -2.026673 -0.322057
4 foo two 0.411452 -0.954371
5 bar two 0.765878 -0.095968
6 foo one -0.654890 0.678091
7 foo three -1.789842 -1.130922
Các lệnh sau hoạt động:
> df.groupby('A').apply(lambda x: (x['C'] - x['D']))
> df.groupby('A').apply(lambda x: (x['C'] - x['D']).mean())
nhưng không có công việc nào sau đây:
> df.groupby('A').transform(lambda x: (x['C'] - x['D']))
ValueError: could not broadcast input array from shape (5) into shape (5,3)
> df.groupby('A').transform(lambda x: (x['C'] - x['D']).mean())
TypeError: cannot concatenate a non-NDFrame object
Tại sao? Ví dụ trên tài liệu dường như gợi ý rằng việc gọi transform
một nhóm cho phép một người thực hiện xử lý thao tác theo hàng:
# Note that the following suggests row-wise operation (x.mean is the column mean)
zscore = lambda x: (x - x.mean()) / x.std()
transformed = ts.groupby(key).transform(zscore)
Nói cách khác, tôi nghĩ rằng biến đổi về cơ bản là một loại áp dụng cụ thể (loại không tổng hợp). Tôi sai ở đâu
Để tham khảo, bên dưới là việc xây dựng khung dữ liệu gốc ở trên:
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : randn(8), 'D' : randn(8)})
zscore
), transform
sẽ nhận được hàm lambda giả sử mỗi mục x
là một mục trong group
và cũng trả về một giá trị cho mỗi mục trong nhóm. Tôi đang thiếu gì?
apply
truyền trong toàn bộ df, nhưng transform
truyền từng cột riêng lẻ dưới dạng Sê-ri. 2) apply
có thể trả về bất kỳ đầu ra hình dạng nào (vô hướng / Sê-ri / Khung dữ liệu / mảng / danh sách ...), trong khi transform
phải trả về một chuỗi (1D Sê-ri / mảng / danh sách) có cùng độ dài với nhóm. Đó là lý do tại sao OP apply()
không cần transform()
. Đây là một câu hỏi hay vì tài liệu không giải thích rõ ràng cả hai sự khác biệt. (gần giống với sự khác biệt giữa apply/map/applymap
hoặc những thứ khác ...)
transform
phải trả về một số, một hàng hoặc hình dạng giống như đối số. nếu đó là một số thì số đó sẽ được đặt thành tất cả các thành phần trong nhóm, nếu đó là một hàng, nó sẽ được phát cho tất cả các hàng trong nhóm. Trong mã của bạn, hàm lambda trả về một cột không thể được phát cho nhóm.