Pandas sử dụng quy tắc nào để tạo chế độ xem so với bản sao?


118

Tôi bối rối về các quy tắc mà Pandas sử dụng khi quyết định rằng lựa chọn từ khung dữ liệu là bản sao của khung dữ liệu gốc hay chế độ xem trên bản gốc.

Ví dụ: nếu tôi có

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

Tôi hiểu rằng querymột bản sao trả về một bản sao giống như

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40

sẽ không ảnh hưởng đến khung dữ liệu ban đầu , df. Tôi cũng hiểu rằng các lát cắt vô hướng hoặc được đặt tên trả về một chế độ xem, do đó các phép gán cho chúng, chẳng hạn như

df.iloc[3] = 70

hoặc là

df.ix[1,'B':'E'] = 222

sẽ thay đổi df. Nhưng tôi bị lạc khi nói đến những trường hợp phức tạp hơn. Ví dụ,

df[df.C <= df.B] = 7654321

thay đổi df, nhưng

df[df.C <= df.B].ix[:,'B':'E']

không làm.

Có một quy tắc đơn giản nào mà Pandas đang sử dụng mà tôi đang thiếu không? Điều gì đang xảy ra trong những trường hợp cụ thể này; và đặc biệt, làm cách nào để thay đổi tất cả các giá trị (hoặc một tập hợp con giá trị) trong khung dữ liệu đáp ứng một truy vấn cụ thể (như tôi đang cố gắng thực hiện trong ví dụ cuối cùng ở trên)?


Lưu ý: Điều này không giống với câu hỏi này ; và tôi đã đọc tài liệu , nhưng không hiểu nó. Tôi cũng đã đọc qua các câu hỏi "Có liên quan" về chủ đề này, nhưng tôi vẫn thiếu quy tắc đơn giản mà Pandas đang sử dụng và cách tôi áp dụng quy tắc đó - ví dụ - sửa đổi các giá trị (hoặc một tập hợp con giá trị) trong khung dữ liệu đáp ứng một truy vấn cụ thể.

Câu trả lời:


138

Đây là các quy tắc, ghi đè tiếp theo:

  • Tất cả các hoạt động tạo ra một bản sao

  • Nếu inplace=Trueđược cung cấp, nó sẽ sửa đổi tại chỗ; chỉ một số hoạt động hỗ trợ điều này

  • Một bộ lập chỉ mục, ví dụ: .loc/.iloc/.iat/.atsẽ đặt ở vị trí.

  • Một trình lập chỉ mục có trên một đối tượng được gõ đơn hầu như luôn luôn là một dạng xem (tùy thuộc vào bố cục bộ nhớ, đó có thể không phải là lý do tại sao điều này không đáng tin cậy). Điều này chủ yếu là để hiệu quả. (ví dụ ở trên là for .query; điều này sẽ luôn trả về một bản sao được đánh giá bởi numexpr)

  • Một trình chỉ mục có trên một đối tượng nhiều kiểu luôn là một bản sao.

Ví dụ của bạn về chained indexing

df[df.C <= df.B].loc[:,'B':'E']

không được đảm bảo hoạt động (và do đó bạn không bao giờ làm điều này).

Thay vào đó hãy làm:

df.loc[df.C <= df.B, 'B':'E']

vì điều này nhanh hơn và sẽ luôn hoạt động

Việc lập chỉ mục chuỗi là 2 hoạt động python riêng biệt và do đó gấu trúc không thể chặn một cách đáng tin cậy (đôi khi bạn sẽ nhận được một SettingWithCopyWarning, nhưng điều đó cũng không thể phát hiện được 100%). Tài liệu dành cho nhà phát triển , mà bạn đã chỉ ra, đưa ra lời giải thích đầy đủ hơn nhiều.


3
.queryLUÔN LUÔN sẽ trả về một bản sao vì những gì nó đang làm (chứ không phải một chế độ xem), bởi vì nó được đánh giá bởi n numberxpr. Vì vậy, tôi sẽ thêm điều đó vào 'quy tắc'
Jeff

3
pandas dựa vào numpy để xác định xem một lượt xem có được tạo hay không. Trong một trường hợp loại dtype duy nhất (có thể là 1-d cho chuỗi, 2-d cho khung, v.v.). numpy có thể tạo ra một lượt xem; nó phụ thuộc vào những gì bạn đang cắt; đôi khi bạn có thể xem và đôi khi bạn không thể. gấu trúc hoàn toàn không dựa vào thực tế này vì nó không phải lúc nào cũng rõ ràng liệu một lượt xem có được tạo hay không. nhưng điều này không quan trọng vì loc không dựa vào điều này khi thiết lập. Tuy nhiên, khi chuỗi lập chỉ mục này là rất quan trọng (và do đó tại sao chuỗi indexing là xấu)
Jeff

3
Rất cảm ơn Jeff, câu trả lời của bạn là hữu ích nhất. Nguồn / tài liệu tham khảo của bạn về chủ đề này là gì?
Kamixave

4
Sau đó, đầu tiên, cảm ơn vì công việc tuyệt vời của bạn! Và thứ hai, nếu bạn có đủ thời gian, tôi nghĩ sẽ rất tuyệt nếu bạn thêm một đoạn văn tương tự như câu trả lời chính của bạn trong tài liệu.
Kamixave

2
chắc chắn sẽ có một yêu cầu kéo để thêm / sửa đổi các tài liệu. cứ liều thử đi.
Jeff
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.