Đối số 'cấp độ', 'khóa' và tên trong hàm concat của Pandas là gì?


94

Câu hỏi

  • Tôi sử dụng pd.concatnhư thế nào?
  • Là gì levelslập luận gì?
  • Là gì keyslập luận gì?
  • Có rất nhiều ví dụ để giúp giải thích cách sử dụng tất cả các đối số không?

concatChức năng của Pandas là con dao của Quân đội Thụy Sĩ trong số các tiện ích hợp nhất. Rất nhiều tình huống mà nó hữu ích. Tài liệu hiện có đưa ra một vài chi tiết về một số đối số tùy chọn. Trong số đó có các đối số levelskeys. Tôi bắt đầu tìm hiểu xem những lập luận đó có tác dụng gì.

Tôi sẽ đặt ra một câu hỏi sẽ hoạt động như một cửa ngõ vào nhiều khía cạnh của pd.concat.

Hãy xem xét các khung dữ liệu d1, d2d3:

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), [2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), [1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), [1, 3])

Nếu tôi nối chúng với nhau với

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'])

Tôi nhận được kết quả mong đợi với một đối tượng pandas.MultiIndexcủa tôi columns:

        A    B    C    D
d1 2  0.1  0.2  0.3  NaN
   3  0.1  0.2  0.3  NaN
d2 1  NaN  0.4  0.5  0.6
   2  NaN  0.4  0.5  0.6
d3 1  0.7  0.8  NaN  0.9
   3  0.7  0.8  NaN  0.9

Tuy nhiên, tôi muốn sử dụng levelstài liệu đối số :

cấp độ : danh sách các chuỗi, mặc định Không có. Các mức cụ thể (giá trị duy nhất) để sử dụng để tạo MultiIndex. Nếu không, chúng sẽ được suy ra từ các phím.

Vì vậy, tôi đã vượt qua

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2']])

Và nhận được một KeyError

ValueError: Key d3 not in level Index(['d1', 'd2'], dtype='object')

Điều này có ý nghĩa. Các cấp độ tôi đã vượt qua không đủ để mô tả các cấp độ cần thiết được chỉ ra bởi các phím. Nếu tôi không vượt qua bất cứ điều gì, như tôi đã làm ở trên, các cấp được suy ra (như đã nêu trong tài liệu). Nhưng làm cách nào khác tôi có thể sử dụng đối số này để có hiệu quả tốt hơn?

Nếu tôi đã thử điều này thay thế:

pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3']])

Tôi và nhận được kết quả tương tự như trên. Nhưng khi tôi thêm một giá trị nữa vào các cấp,

df = pd.concat([d1, d2, d3], keys=['d1', 'd2', 'd3'], levels=[['d1', 'd2', 'd3', 'd4']])

Tôi kết thúc với cùng một khung dữ liệu, nhưng kết quả MultiIndexcó mức không sử dụng.

df.index.levels[0]

Index(['d1', 'd2', 'd3', 'd4'], dtype='object')

Vậy mục đích của levellập luận là gì và tôi có nên sử dụng cách keyskhác không?

Tôi đang sử dụng Python 3.6 và Pandas 0.22.

Câu trả lời:


124

Trong quá trình trả lời câu hỏi này cho bản thân, tôi đã học được nhiều điều, và tôi muốn tập hợp một danh mục các ví dụ và một số giải thích.

Câu trả lời cụ thể cho quan điểm của cuộc levelstranh luận sẽ đến ở phần cuối.

pandas.concat: Hướng dẫn sử dụng còn thiếu

Liên kết đến tài liệu hiện tại

Nhập và xác định đối tượng

import pandas as pd

d1 = pd.DataFrame(dict(A=.1, B=.2, C=.3), index=[2, 3])
d2 = pd.DataFrame(dict(B=.4, C=.5, D=.6), index=[1, 2])
d3 = pd.DataFrame(dict(A=.7, B=.8, D=.9), index=[1, 3])

s1 = pd.Series([1, 2], index=[2, 3])
s2 = pd.Series([3, 4], index=[1, 2])
s3 = pd.Series([5, 6], index=[1, 3])

Tranh luận

objs

Đối số đầu tiên mà chúng ta gặp phải là objs:

objs : một chuỗi hoặc ánh xạ của các đối tượng Series, DataFrame hoặc Panel Nếu một dict được chuyển, các khóa đã sắp xếp sẽ được sử dụng làm đối số khóa, trừ khi nó được truyền, trong trường hợp đó các giá trị sẽ được chọn (xem bên dưới). Mọi đối tượng Không có sẽ bị loại bỏ âm thầm trừ khi tất cả chúng đều Không có. Trong trường hợp đó, một ValueError sẽ được nâng lên

  • Chúng tôi thường thấy điều này được sử dụng với một danh sách Serieshoặc DataFramecác đối tượng.
  • Tôi sẽ chỉ ra rằng điều đó dictcũng có thể rất hữu ích.
  • Máy phát điện cũng có thể được sử dụng và có thể hữu ích khi sử dụng mapnhư trongmap(f, list_of_df)

Bây giờ, chúng ta sẽ gắn bó với danh sách một số đối tượng DataFrameSeriesđối tượng được xác định ở trên. Tôi sẽ chỉ ra cách tận dụng từ điển để đưa ra những MultiIndexkết quả rất hữu ích sau này.

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

axis

Đối số thứ hai mà chúng ta gặp phải axiscó giá trị mặc định là 0:

trục : {0 / 'index', 1 / 'cột'}, mặc định là 0 Trục để nối với nhau.

Hai DataFrames với axis=0(xếp chồng lên nhau)

Đối với các giá trị của 0hoặc indexchúng tôi muốn nói: "Căn chỉnh dọc theo các cột và thêm vào chỉ mục".

Như được hiển thị ở trên nơi chúng tôi đã sử dụng axis=0, vì 0là giá trị mặc định và chúng tôi thấy rằng chỉ mục của d2mở rộng chỉ mục của d1mặc dù có sự chồng chéo của giá trị 2:

pd.concat([d1, d2], axis=0)

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

Hai DataFrames với axis=1(cạnh nhau)

Đối với các giá trị 1hoặc columnschúng tôi muốn nói: "Căn chỉnh theo chỉ mục và thêm vào các cột",

pd.concat([d1, d2], axis=1)

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

Chúng ta có thể thấy rằng chỉ mục kết quả là sự kết hợp của các chỉ số và các cột kết quả là phần mở rộng của các cột từ d1các cột của d2.

Hai (hoặc Ba) Seriesvới axis=0(xếp chồng lên nhau)

Khi kết hợp pandas.Seriescùng nhau axis=0, chúng ta nhận được lại a pandas.Series. Tên của kết quả Seriessẽ là Nonetrừ khi tất cả Seriesđược kết hợp có cùng tên. Hãy chú ý đến thời 'Name: A'điểm chúng tôi in ra kết quả Series. Khi nó không có mặt, chúng ta có thể cho rằng Seriestên là None.

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('A'),
 pd.concat(    |      [s1.rename('A'), |      [s1.rename('A'),  |       s2.rename('B'),
     [s1, s2]) |       s2])            |       s2.rename('A')]) |       s3.rename('A')])
-------------- | --------------------- | ---------------------- | ----------------------
2    1         | 2    1                | 2    1                 | 2    1
3    2         | 3    2                | 3    2                 | 3    2
1    3         | 1    3                | 1    3                 | 1    3
2    4         | 2    4                | 2    4                 | 2    4
dtype: int64   | dtype: int64          | Name: A, dtype: int64  | 1    5
               |                       |                        | 3    6
               |                       |                        | dtype: int64

Hai (hoặc Ba) Seriesvới axis=1(cạnh nhau)

Khi kết hợp pandas.Seriescùng axis=1, nó là namethuộc tính mà chúng tôi tham chiếu đến để suy ra tên cột trong kết quả pandas.DataFrame.

                       |                       |  pd.concat(
                       |  pd.concat(           |      [s1.rename('X'),
 pd.concat(            |      [s1.rename('X'), |       s2.rename('Y'),
     [s1, s2], axis=1) |       s2], axis=1)    |       s3.rename('Z')], axis=1)
---------------------- | --------------------- | ------------------------------
     0    1            |      X    0           |      X    Y    Z
1  NaN  3.0            | 1  NaN  3.0           | 1  NaN  3.0  5.0
2  1.0  4.0            | 2  1.0  4.0           | 2  1.0  4.0  NaN
3  2.0  NaN            | 3  2.0  NaN           | 3  2.0  NaN  6.0

Hỗn hợp SeriesDataFramevới axis=0(xếp chồng lên nhau)

Khi thực hiện nối a SeriesDataFramecùng axis=0, chúng ta chuyển tất cả Seriesthành cột đơn DataFrames.

Hãy đặc biệt lưu ý rằng đây là một nối cùng axis=0; điều đó có nghĩa là mở rộng chỉ mục (hàng) trong khi căn chỉnh các cột. Trong các ví dụ dưới đây, chúng ta thấy chỉ số trở thành [2, 3, 2, 3]một chỉ số nối tiếp một cách bừa bãi. Các cột không chồng lên nhau trừ khi tôi buộc đặt tên của Seriescột với đối số là to_frame:

 pd.concat(               |
     [s1.to_frame(), d1]) |  pd.concat([s1, d1])
------------------------- | ---------------------
     0    A    B    C     |      0    A    B    C
2  1.0  NaN  NaN  NaN     | 2  1.0  NaN  NaN  NaN
3  2.0  NaN  NaN  NaN     | 3  2.0  NaN  NaN  NaN
2  NaN  0.1  0.2  0.3     | 2  NaN  0.1  0.2  0.3
3  NaN  0.1  0.2  0.3     | 3  NaN  0.1  0.2  0.3

Bạn có thể thấy kết quả của pd.concat([s1, d1])giống như thể tôi đã to_frametự làm sạch.

Tuy nhiên, tôi có thể kiểm soát tên của cột kết quả với một tham số là to_frame. Đổi tên Seriesvới renamephương thức không kiểm soát tên cột trong kết quả DataFrame.

 # Effectively renames       |                            |
 # `s1` but does not align   |  # Does not rename.  So    |  # Renames to something
 # with columns in `d1`      |  # Pandas defaults to `0`  |  # that does align with `d1`
 pd.concat(                  |  pd.concat(                |  pd.concat(
     [s1.to_frame('X'), d1]) |      [s1.rename('X'), d1]) |      [s1.to_frame('B'), d1])
---------------------------- | -------------------------- | ----------------------------
     A    B    C    X        |      0    A    B    C      |      A    B    C
2  NaN  NaN  NaN  1.0        | 2  1.0  NaN  NaN  NaN      | 2  NaN  1.0  NaN
3  NaN  NaN  NaN  2.0        | 3  2.0  NaN  NaN  NaN      | 3  NaN  2.0  NaN
2  0.1  0.2  0.3  NaN        | 2  NaN  0.1  0.2  0.3      | 2  0.1  0.2  0.3
3  0.1  0.2  0.3  NaN        | 3  NaN  0.1  0.2  0.3      | 3  0.1  0.2  0.3

Hỗn hợp SeriesDataFramevới axis=1(cạnh nhau)

Điều này là khá trực quan. Seriestên cột mặc định là danh sách các Seriesđối tượng như vậy khi namekhông có thuộc tính.

                    |  pd.concat(
 pd.concat(         |      [s1.rename('X'),
     [s1, d1],      |       s2, s3, d1],
     axis=1)        |      axis=1)
------------------- | -------------------------------
   0    A    B    C |      X    0    1    A    B    C
2  1  0.1  0.2  0.3 | 1  NaN  3.0  5.0  NaN  NaN  NaN
3  2  0.1  0.2  0.3 | 2  1.0  4.0  NaN  0.1  0.2  0.3
                    | 3  2.0  NaN  6.0  0.1  0.2  0.3

join

Đối số thứ ba joinmô tả liệu hợp nhất kết quả nên là hợp nhất bên ngoài (mặc định) hay hợp nhất bên trong.

join : {'inside', 'external'}, default 'external'
Cách xử lý các chỉ mục trên (các) trục khác.

Hóa ra, không có lefthoặc righttùy chọn pd.concatcó thể xử lý nhiều hơn hai đối tượng để hợp nhất.

Trong trường hợp d1d2, các tùy chọn trông giống như:

outer

pd.concat([d1, d2], axis=1, join='outer')

     A    B    C    B    C    D
1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN

inner

pd.concat([d1, d2], axis=1, join='inner')

     A    B    C    B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6

join_axes

Đối số thứ tư là thứ cho phép chúng tôi thực hiện lefthợp nhất và hơn thế nữa.

join_axes : danh sách các đối tượng Chỉ mục Chỉ mục
cụ thể để sử dụng cho n - 1 trục khác thay vì thực hiện logic tập hợp bên trong / bên ngoài.

Hợp nhất trái

pd.concat([d1, d2, d3], axis=1, join_axes=[d1.index])

     A    B    C    B    C    D    A    B    D
2  0.1  0.2  0.3  0.4  0.5  0.6  NaN  NaN  NaN
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

Hợp nhất bên phải

pd.concat([d1, d2, d3], axis=1, join_axes=[d3.index])

     A    B    C    B    C    D    A    B    D
1  NaN  NaN  NaN  0.4  0.5  0.6  0.7  0.8  0.9
3  0.1  0.2  0.3  NaN  NaN  NaN  0.7  0.8  0.9

ignore_index

ignore_index : boolean, mặc định Sai
Nếu Đúng, không sử dụng các giá trị chỉ mục dọc theo trục nối. Trục kết quả sẽ được gắn nhãn 0, ..., n - 1. Điều này rất hữu ích nếu bạn đang nối các đối tượng mà trục nối không có thông tin chỉ mục có ý nghĩa. Lưu ý rằng các giá trị chỉ mục trên các trục khác vẫn được tôn trọng trong phép nối.

Giống như khi tôi xếp chồng d1lên nhau d2, nếu tôi không quan tâm đến các giá trị chỉ mục, tôi có thể đặt lại chúng hoặc bỏ qua chúng.

                      |  pd.concat(             |  pd.concat(
                      |      [d1, d2],          |      [d1, d2]
 pd.concat([d1, d2])  |      ignore_index=True) |  ).reset_index(drop=True)
--------------------- | ----------------------- | -------------------------
     A    B    C    D |      A    B    C    D   |      A    B    C    D
2  0.1  0.2  0.3  NaN | 0  0.1  0.2  0.3  NaN   | 0  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN | 1  0.1  0.2  0.3  NaN   | 1  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6 | 2  NaN  0.4  0.5  0.6   | 2  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6 | 3  NaN  0.4  0.5  0.6   | 3  NaN  0.4  0.5  0.6

Và khi sử dụng axis=1:

                                   |     pd.concat(
                                   |         [d1, d2], axis=1,
 pd.concat([d1, d2], axis=1)       |         ignore_index=True)
-------------------------------    |    -------------------------------
     A    B    C    B    C    D    |         0    1    2    3    4    5
1  NaN  NaN  NaN  0.4  0.5  0.6    |    1  NaN  NaN  NaN  0.4  0.5  0.6
2  0.1  0.2  0.3  0.4  0.5  0.6    |    2  0.1  0.2  0.3  0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN    |    3  0.1  0.2  0.3  NaN  NaN  NaN

keys

Chúng ta có thể chuyển một danh sách các giá trị vô hướng hoặc các bộ giá trị để gán các bộ giá trị hoặc bộ giá trị vô hướng cho MultiIndex tương ứng. Độ dài của danh sách đã thông qua phải bằng độ dài với số mục được nối.

các phím : trình tự, mặc định Không có
Nếu nhiều cấp được vượt qua, phải chứa các bộ giá trị. Xây dựng chỉ mục phân cấp bằng cách sử dụng các khóa được truyền làm cấp ngoài cùng

axis=0

Khi nối Seriescác đối tượng dọc theo axis=0(mở rộng chỉ mục).

Các khóa đó, trở thành cấp ban đầu mới của một MultiIndexđối tượng trong thuộc tính chỉ mục.

 #           length 3             length 3           #         length 2        length 2
 #          /--------\         /-----------\         #          /----\         /------\
 pd.concat([s1, s2, s3], keys=['A', 'B', 'C'])       pd.concat([s1, s2], keys=['A', 'B'])
----------------------------------------------      -------------------------------------
A  2    1                                           A  2    1
   3    2                                              3    2
B  1    3                                           B  1    3
   2    4                                              2    4
C  1    5                                           dtype: int64
   3    6
dtype: int64

Tuy nhiên, chúng ta có thể sử dụng nhiều hơn các giá trị vô hướng trong keys đối số để tạo ra một sâu hơn MultiIndex. Ở đây chúng ta vượt qua tuplesđộ dài 2 để thêm vào trước hai cấp độ mới của a MultiIndex:

 pd.concat(
     [s1, s2, s3],
     keys=[('A', 'X'), ('A', 'Y'), ('B', 'X')])
-----------------------------------------------
A  X  2    1
      3    2
   Y  1    3
      2    4
B  X  1    5
      3    6
dtype: int64

axis=1

Nó hơi khác một chút khi mở rộng dọc theo các cột. Khi chúng tôi sử dụng axis=0(xem ở trên), chúng tôi keyshoạt động như MultiIndexcác cấp ngoài chỉ mục hiện có. Vì axis=1, chúng tôi đang đề cập đến một trục mà Seriescác đối tượng không có, đó là columnsthuộc tính.

Các biến thể của Two Serieswtihaxis=1

Lưu ý rằng đặt tên cho s1s2các vấn đề miễn là không keysđược thông qua, nhưng nó sẽ bị ghi đè nếu keysđược thông qua.

               |                       |                        |  pd.concat(
               |  pd.concat(           |  pd.concat(            |      [s1.rename('U'),
 pd.concat(    |      [s1, s2],        |      [s1.rename('U'),  |       s2.rename('V')],
     [s1, s2], |      axis=1,          |       s2.rename('V')], |       axis=1,
     axis=1)   |      keys=['X', 'Y']) |       axis=1)          |       keys=['X', 'Y'])
-------------- | --------------------- | ---------------------- | ----------------------
     0    1    |      X    Y           |      U    V            |      X    Y
1  NaN  3.0    | 1  NaN  3.0           | 1  NaN  3.0            | 1  NaN  3.0
2  1.0  4.0    | 2  1.0  4.0           | 2  1.0  4.0            | 2  1.0  4.0
3  2.0  NaN    | 3  2.0  NaN           | 3  2.0  NaN            | 3  2.0  NaN
MultiIndexvới Seriesaxis=1
 pd.concat(
     [s1, s2],
     axis=1,
     keys=[('W', 'X'), ('W', 'Y')])
-----------------------------------
     W
     X    Y
1  NaN  3.0
2  1.0  4.0
3  2.0  NaN
Hai DataFramevớiaxis=1

Như với các axis=0ví dụ, hãy keysthêm cấp độ vào a MultiIndex, nhưng lần này là đối tượng được lưu trữ trong columnsthuộc tính.

 pd.concat(                     |  pd.concat(
     [d1, d2],                  |      [d1, d2],
     axis=1,                    |      axis=1,
     keys=['X', 'Y'])           |      keys=[('First', 'X'), ('Second', 'X')])
------------------------------- | --------------------------------------------
     X              Y           |   First           Second
     A    B    C    B    C    D |       X                X
1  NaN  NaN  NaN  0.4  0.5  0.6 |       A    B    C      B    C    D
2  0.1  0.2  0.3  0.4  0.5  0.6 | 1   NaN  NaN  NaN    0.4  0.5  0.6
3  0.1  0.2  0.3  NaN  NaN  NaN | 2   0.1  0.2  0.3    0.4  0.5  0.6
                                | 3   0.1  0.2  0.3    NaN  NaN  NaN
SeriesDataFramevớiaxis=1

Điều này là khó khăn. Trong trường hợp này, giá trị khóa vô hướng không thể hoạt động như cấp chỉ mục duy nhất cho Seriesđối tượng khi nó trở thành một cột trong khi cũng hoạt động như cấp đầu tiên của a MultiIndexcho DataFrame. Vì vậy, Pandas sẽ lại sử dụng namethuộc tính của Seriesđối tượng làm nguồn của tên cột.

 pd.concat(           |  pd.concat(
     [s1, d1],        |      [s1.rename('Z'), d1],
     axis=1,          |      axis=1,
     keys=['X', 'Y']) |      keys=['X', 'Y'])
--------------------- | --------------------------
   X    Y             |    X    Y
   0    A    B    C   |    Z    A    B    C
2  1  0.1  0.2  0.3   | 2  1  0.1  0.2  0.3
3  2  0.1  0.2  0.3   | 3  2  0.1  0.2  0.3
Hạn chế của keysvà suy luận MultiIndex.

Con gấu trúc dường như chỉ suy ra tên cột từ Seriestên, nhưng nó sẽ không điền vào chỗ trống khi thực hiện nối tương tự giữa các khung dữ liệu có số lượng cấp cột khác nhau.

d1_ = pd.concat(
    [d1], axis=1,
    keys=['One'])
d1_

   One
     A    B    C
2  0.1  0.2  0.3
3  0.1  0.2  0.3

Sau đó, nối khung dữ liệu này với một khung dữ liệu khác chỉ có một cấp trong đối tượng cột và Pandas sẽ từ chối thử tạo các bộ giá trị của MultiIndexđối tượng và kết hợp tất cả các khung dữ liệu như thể một cấp độ duy nhất của các đối tượng, vô hướng và bộ giá trị.

pd.concat([d1_, d2], axis=1)

   (One, A)  (One, B)  (One, C)    B    C    D
1       NaN       NaN       NaN  0.4  0.5  0.6
2       0.1       0.2       0.3  0.4  0.5  0.6
3       0.1       0.2       0.3  NaN  NaN  NaN

Vượt qua một dictthay vì mộtlist

Khi truyền từ điển, pandas.concatsẽ sử dụng các khóa từ từ điển làm keystham số.

 # axis=0               |  # axis=1
 pd.concat(             |  pd.concat(
     {0: d1, 1: d2})    |      {0: d1, 1: d2}, axis=1)
----------------------- | -------------------------------
       A    B    C    D |      0              1
0 2  0.1  0.2  0.3  NaN |      A    B    C    B    C    D
  3  0.1  0.2  0.3  NaN | 1  NaN  NaN  NaN  0.4  0.5  0.6
1 1  NaN  0.4  0.5  0.6 | 2  0.1  0.2  0.3  0.4  0.5  0.6
  2  NaN  0.4  0.5  0.6 | 3  0.1  0.2  0.3  NaN  NaN  NaN

levels

Điều này được sử dụng cùng với keysđối số. Khi levelsđược để làm giá trị mặc định của nó None, Pandas sẽ lấy các giá trị duy nhất của mỗi cấp của kết quả MultiIndexvà sử dụng nó làm đối tượng được sử dụng trong index.levelsthuộc tính kết quả .

cấp độ : danh sách trình tự, mặc định Không có Cấp
độ cụ thể (giá trị duy nhất) để sử dụng để tạo MultiIndex. Nếu không, chúng sẽ được suy ra từ các phím.

Nếu Pandas đã suy ra những cấp độ này thì có lợi gì để tự mình chỉ định nó? Tôi sẽ đưa ra một ví dụ và để bạn nghĩ ra những lý do khác tại sao điều này có thể hữu ích.

Thí dụ

Theo tài liệu, levelsđối số là một danh sách các chuỗi. Điều này có nghĩa là chúng ta có thể sử dụng cái khác pandas.Indexlàm một trong những chuỗi đó.

Hãy xem xét khung dữ liệu dflà kết nối của d1, d2d3:

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'])

df

  First           Second           Fourth
      A    B    C      B    C    D      A    B    D
1   NaN  NaN  NaN    0.4  0.5  0.6    0.7  0.8  0.9
2   0.1  0.2  0.3    0.4  0.5  0.6    NaN  NaN  NaN
3   0.1  0.2  0.3    NaN  NaN  NaN    0.7  0.8  0.9

Các cấp độ của đối tượng cột là:

print(df, *df.columns.levels, sep='\n')

Index(['First', 'Second', 'Fourth'], dtype='object')
Index(['A', 'B', 'C', 'D'], dtype='object')

Nếu chúng tôi sử dụng sumtrong một, groupbychúng tôi nhận được:

df.groupby(axis=1, level=0).sum()

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

Nhưng điều gì sẽ xảy ra nếu thay vì ['First', 'Second', 'Fourth']có một danh mục bị thiếu khác được đặt tên ThirdFifth? Và tôi muốn chúng được đưa vào kết quả của một groupbytổng hợp? Chúng tôi có thể làm điều này nếu chúng tôi có pandas.CategoricalIndex. Và chúng tôi có thể chỉ định điều đó trước vớilevels đối số.

Vì vậy, thay vào đó, hãy định nghĩa dflà:

cats = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
lvl = pd.CategoricalIndex(cats, categories=cats, ordered=True)

df = pd.concat(
    [d1, d2, d3], axis=1,
    keys=['First', 'Second', 'Fourth'],
    levels=[lvl]
)

df

   First  Fourth  Second
1    0.0     2.4     1.5
2    0.6     0.0     1.5
3    0.6     2.4     0.0

Nhưng mức đầu tiên của đối tượng cột là:

df.columns.levels[0]

CategoricalIndex(
    ['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    categories=['First', 'Second', 'Third', 'Fourth', 'Fifth'],
    ordered=True, dtype='category')

groupbytổng kết của chúng tôi trông giống như:

df.groupby(axis=1, level=0).sum()

   First  Second  Third  Fourth  Fifth
1    0.0     1.5    0.0     2.4    0.0
2    0.6     1.5    0.0     0.0    0.0
3    0.6     0.0    0.0     2.4    0.0

names

Điều này được sử dụng để đặt tên cho các mức của một kết quả MultiIndex. Độ dài của namesdanh sách phải khớp với số cấp trong kết quả MultiIndex.

tên : danh sách, mặc định Không có
Tên cho các cấp trong chỉ mục phân cấp kết quả

 # axis=0                     |  # axis=1
 pd.concat(                   |  pd.concat(
     [d1, d2],                |      [d1, d2],
     keys=[0, 1],             |      axis=1, keys=[0, 1],
     names=['lvl0', 'lvl1'])  |      names=['lvl0', 'lvl1'])
----------------------------- | ----------------------------------
             A    B    C    D | lvl0    0              1
lvl0 lvl1                     | lvl1    A    B    C    B    C    D
0    2     0.1  0.2  0.3  NaN | 1     NaN  NaN  NaN  0.4  0.5  0.6
     3     0.1  0.2  0.3  NaN | 2     0.1  0.2  0.3  0.4  0.5  0.6
1    1     NaN  0.4  0.5  0.6 | 3     0.1  0.2  0.3  NaN  NaN  NaN
     2     NaN  0.4  0.5  0.6 |

verify_integrity

Tài liệu tự giải thích

verify_integrity : boolean, default False
Kiểm tra xem trục nối mới có chứa các bản sao không. Điều này có thể rất tốn kém so với việc ghép dữ liệu thực tế.

Bởi vì chỉ mục kết quả từ việc nối d1d2không phải là duy nhất, nó sẽ không kiểm tra được tính toàn vẹn.

pd.concat([d1, d2])

     A    B    C    D
2  0.1  0.2  0.3  NaN
3  0.1  0.2  0.3  NaN
1  NaN  0.4  0.5  0.6
2  NaN  0.4  0.5  0.6

pd.concat([d1, d2], verify_integrity=True)

> ValueError: Các chỉ mục có các giá trị chồng chéo: [2]


23
sẽ thực sự hữu ích hơn nhiều đối với cộng đồng nếu chỉ cần thực hiện một yêu cầu kéo để thêm một số ví dụ còn thiếu (chỉ một vài) vào các tài liệu chính; SO chỉ có thể tìm kiếm và không thể duyệt; Việc đặt thêm một liên kết đến các tài liệu sẽ rất hữu ích ở đây - phần lớn điều này đã được ghi chép đầy đủ và tốt
Jeff

6
@Jeff, có những chiều tăng trưởng của tôi chậm. Sử dụng git là một trong số đó. Tôi hứa đó là những gì tôi muốn bắt đầu làm.
piRSquared

Sử dụng pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum()tạo ra một kết quả khác với pd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum(). Bạn có biết tại sao? Các tài liệu chỉ nói levelsnên là một danh sách các trình tự.
unutbu

1
Câu trả lời tuyệt vời, nhưng tôi nghĩ rằng phần trên Passing a dict instead of a list cần một ví dụ bằng cách sử dụng một chính tả, không phải một danh sách.
unutbu

1
@unutbu Tôi đã sửa dictví dụ, thx. Lý do tại sao đó lvllà một chỉ mục phân loại và catschỉ là một danh sách. Khi nhóm theo loại phân loại, các danh mục bị thiếu sẽ được điền bằng số không và giá trị rỗng nếu thích hợp. Xem cái này
piRSquared
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.