Для чого потрібні аргументи "рівні", "ключі" та імена у функції concat від Pandas?


94

Питання

  • Як я використовую pd.concat?
  • Для чого levelsаргумент?
  • Для чого keysаргумент?
  • Чи є купа прикладів, які допоможуть пояснити, як використовувати всі аргументи?

concatФункція Пандаса - це швейцарський армійський ніж комунальних служб. Різноманітність ситуацій, в яких це корисно, безліч. Існуюча документація залишає кілька деталей щодо деяких необов’язкових аргументів. Серед них є levelsі keysаргументи. Я вирішив з’ясувати, що роблять ці аргументи.

Я поставлю питання, яке буде діяти як шлюз у багато аспектів pd.concat.

Розглянемо кадри даних d1, d2і d3:

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])

Якби я об'єднав їх разом із

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

Я отримую очікуваний результат за допомогою pandas.MultiIndexмого 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

Однак я хотів використати levelsдокументацію аргументу :

рівні : список послідовностей, за замовчуванням Немає. Конкретні рівні (унікальні значення), які слід використовувати для побудови MultiIndex. В іншому випадку вони будуть виведені з ключів.

Тож я пройшов

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

І отримати KeyError

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

Це мало сенс. Рівні, які я пройшов, були недостатні для опису необхідних рівнів, позначених клавішами. Якби я нічого не пройшов, як це було вище, рівні визначаються (як зазначено в документації). Але як ще я можу використати цей аргумент для кращого ефекту?

Якби я спробував це замість цього:

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

Я і отримав ті самі результати, що і вище. Але коли я додаю ще одне значення до рівнів,

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

У підсумку я отримую такий самий вигляд кадру даних, але отриманий MultiIndexмає невикористаний рівень.

df.index.levels[0]

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

Тож у чому сенс levelаргументу, і чи повинен я використовувати keysінакше?

Я використовую Python 3.6 та Pandas 0.22.

Відповіді:


124

У процесі відповіді на це запитання для себе я дізнався багато речей і хотів скласти каталог прикладів та пояснення.

Конкретна відповідь на суть levelsаргументу прийде до кінця.

pandas.concat: Зниклий посібник

Посилання на поточну документацію

Імпорт та визначення об'єктів

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])

Аргументи

objs

Перший аргумент, з яким ми стикаємось objs:

objs : послідовність або відображення об'єктів Series, DataFrame або Panel. Якщо передано dict, відсортовані ключі будуть використовуватися як аргумент ключів, якщо він не переданий, і в цьому випадку будуть вибрані значення (див. нижче). Будь-які об’єкти None буде скинуто без звуку, якщо вони не є усі None, і в такому випадку буде піднято ValueError

  • Зазвичай ми бачимо, що це використовується зі списком Seriesабо DataFrameоб’єктами.
  • Я покажу, що це також dictможе бути дуже корисним.
  • Також можуть використовуватися генератори, які можуть бути корисними при використанні mapяк уmap(f, list_of_df)

На даний момент, ми будемо дотримуватися список деяких з DataFrameі Seriesоб'єкти , визначені вище. Я покажу, як можна використовувати словники, щоб дати дуже корисні MultiIndexрезультати пізніше.

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

Другий аргумент, з яким ми стикаємося, - це axisзначення за замовчуванням 0:

вісь : {0 / 'індекс', 1 / 'стовпці'}, за замовчуванням 0 Вісь, що об'єднується вздовж.

Два DataFrames з axis=0(складеними)

Для значень 0або indexми маємо на увазі сказати: "Вирівняти по стовпцях і додати до індексу".

Як показано вище, де ми використовували axis=0, оскільки 0це значення за замовчуванням, і ми бачимо, що індекс d2розширює індекс, d1незважаючи на те, що значення перекривається 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

Два DataFrames з axis=1(поруч)

Для значень 1або columnsми маємо на увазі сказати: "Вирівняти вздовж покажчика та додати до стовпців",

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

Ми бачимо, що отриманий індекс є об'єднанням індексів, а отримані стовпці є розширенням стовпців d1за допомогою стовпців d2.

Два (або три) Seriesз axis=0(складеними)

При об'єднанні pandas.Seriesразом axis=0, ми отримуємо назад pandas.Series. Ім'я отриманого Seriesбуде, Noneякщо тільки всі Seriesоб'єднані не мають однакової назви. Зверніть увагу на те, 'Name: A'коли ми роздруковуємо отримане Series. Коли його немає, ми можемо припустити, що це Seriesім’я 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

Два (або Три) Seriesз axis=1(поруч)

При об'єднанні pandas.Seriesразом axis=1, це nameатрибут , який ми називаємо для того , щоб вивести ім'я стовпця в результуючій 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

Змішані Seriesта DataFrameз axis=0(складеними)

При виконанні конкатенації a Seriesта DataFramealong axis=0ми перетворюємо все Seriesв одинарні стовпці DataFrames.

Зверніть особливу увагу на те, що це конкатенація axis=0; це означає розширення індексу (рядків) під час вирівнювання стовпців. У наведених нижче прикладах ми бачимо, що індекс стає [2, 3, 2, 3]нерозбірливим додаванням індексів. Стовпці не перекриваються, якщо я не змушую називати Seriesстовпець аргументом 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

Ви можете бачити, що результати pd.concat([s1, d1])такі самі, як ніби я пробував to_frameсебе.

Однак я можу керувати назвою отриманого стовпця за допомогою параметра to to_frame. Перейменування методу Seriesза допомогою renameметоду не контролює ім'я стовпця в результаті 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

Змішані Seriesта DataFrameз axis=1(поруч)

Це досить інтуїтивно. SeriesІм'я стовпця за замовчуванням перелічує такі Seriesоб'єкти, коли nameатрибут недоступний.

                    |  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

Третій аргумент joinописує, чи має бути отримане злиття зовнішнім злиттям (за замовчуванням) чи внутрішнім злиттям.

join : {'внутрішній', 'зовнішній'}, за замовчуванням 'зовнішній'
Як обробляти індекси на інших вісях.

Це не виходить, немає leftабо rightваріанти , як pd.concatможе працювати більше , ніж просто два об'єднуються об'єкти.

У разі d1і d2, варіанти виглядати наступним чином :

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

Четвертий аргумент - це те, що дозволяє нам робити leftзлиття та багато іншого.

join_axes : список об’єктів індексу
Специфічні індекси, які слід використовувати для інших осей n - 1 замість виконання логіки внутрішнього / зовнішнього набору.

Ліве злиття

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

Правильне злиття

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, за замовчуванням False
If True, не використовуйте значення індексу вздовж осі конкатенації. Отримана вісь буде позначена як 0, ..., n - 1. Це корисно, якщо ви об'єднуєте об'єкти, де вісь конкатенації не має значущої інформації про індексацію. Зверніть увагу, що значення індексу на інших осях як і раніше поважаються в об'єднанні.

Як коли я складаю d1поверх d2, якщо я не дбаю про значення індексу, я можу скинути їх або проігнорувати.

                      |  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

І при використанні 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

Ми можемо передати список скалярних значень або кортежів, щоб призначити кортеж або скалярні значення відповідному MultiIndex. Довжина переданого списку повинна бути такою ж довжиною, як кількість об’єднаних елементів.

ключі : послідовність, за замовчуванням Немає
Якщо пройдено кілька рівнів, повинен містити кортежі. Побудуйте ієрархічний індекс, використовуючи передані ключі як крайній рівень

axis=0

При об'єднанні Seriesоб'єктів уздовж axis=0(розширення індексу).

Ці ключі стають новим початковим рівнем MultiIndexоб'єкта в атрибуті index.

 #           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

Однак ми можемо використовувати більше, ніж скалярні значення в keysаргументі, щоб створити ще глибше MultiIndex. Тут ми проходимо tuplesдовжину 2, додаємо два нові рівні 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

Трохи інакше це відбувається при протязі вздовж стовпців. Коли ми використовували axis=0(див. Вище), ми keysдіяли як MultiIndexрівні на додаток до існуючого індексу. Адже axis=1ми маємо на увазі вісь, якої Seriesоб’єкти не мають, а саме columnsатрибут.

Варіації два Seriesтрейлерівaxis=1

Зверніть увагу, що іменування s1та s2має значення до тих пір, поки keysне передано no , але воно буде замінено, якщо keysпередано.

               |                       |                        |  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
MultiIndexза допомогою Seriesіaxis=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
Дві DataFrameсaxis=1

Як і в axis=0прикладах, keysдодайте рівні до a MultiIndex, але цього разу до об’єкта, що зберігається в columnsатрибуті.

 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
Seriesі DataFrameсaxis=1

Це складно. У цьому випадку скалярне значення ключа не може виступати єдиним рівнем індексу для Seriesоб'єкта, коли він стає стовпцем, одночасно виконуючи роль першого рівня a MultiIndexдля DataFrame. Тож Pandas знову використовуватиме nameатрибут Seriesоб’єкта як джерело імені стовпця.

 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
Обмеження keysта MultiIndexвисновки.

Панда, здається, лише виводить імена стовпців з Seriesімені, але при заповненні аналогічних конкатенацій серед кадрів даних з різною кількістю рівнів стовпців вона не заповнює порожні місця.

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

Потім об'єднайте це з іншим фреймом даних лише з одним рівнем в об'єкті стовпців, і Pandas відмовиться намагатись робити кортежі MultiIndexоб'єкта та об'єднувати всі кадри даних, як ніби один рівень об'єктів, скалярів та кортежів.

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

Проходячи dictзамість alist

При передачі pandas.concatсловника в якості keysпараметра використовуватимуть ключі зі словника .

 # 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

Це використовується у поєднанні з keysаргументом. Якщо levelsце значення залишається за замовчуванням None, Pandas приймає унікальні значення кожного рівня результуючого MultiIndexі використовує це як об'єкт, що використовується в результуючому index.levelsатрибуті.

рівні : список послідовностей, за замовчуванням Немає
Конкретні рівні (унікальні значення) для використання для побудови MultiIndex. В іншому випадку вони будуть виведені з ключів.

Якщо панди вже припускають, якими мають бути ці рівні, яка перевага є, щоб визначити це самі? Я покажу один приклад і залишаю за вами, щоб ви придумали інші причини, чому це може бути корисним.

Приклад

Відповідно до документації levelsаргументом є список послідовностей. Це означає, що ми можемо використовувати іншу pandas.Indexяк одну з цих послідовностей.

Розглянемо фрейм даних, dfякий є об’єднанням d1, d2і d3:

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

Рівні об'єкта стовпці:

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

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

Якщо ми використовуємо sumв межах a, groupbyто отримуємо:

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

Але що, якби замість ['First', 'Second', 'Fourth']іншої відсутньої категорії були названі Thirdі Fifth? І я хотів, щоб вони були включені в результати groupbyагрегування? Ми можемо зробити це, якби мали pandas.CategoricalIndex. І ми можемо вказати це заздалегідь levelsаргументом.

Тож замість цього давайте визначимо dfяк:

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

Але перший рівень об’єкта стовпців:

df.columns.levels[0]

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

І наше groupbyпідсумовування виглядає так:

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

Це використовується для позначення рівнів результату MultiIndex. Довжина namesсписку повинна відповідати кількості рівнів у результаті MultiIndex.

імена : список, за замовчуванням Немає
Імена рівнів у результуючому ієрархічному індексі

 # 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

Пояснювальна документація

verify_integrity : boolean, за замовчуванням False
Перевірте, чи нова об'єднана вісь містить дублікати. Це може бути дуже дорогим щодо фактичного об’єднання даних.

Оскільки результуючий індекс від об'єднання d1та d2не є унікальним, він не зможе перевірити цілісність.

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: Індекси мають перекриваються значення: [2]


23
дійсно було б набагато кориснішим для спільноти просто зробити запит на витягування, щоб додати кілька відсутніх прикладів (лише пару) до основних документів; SO можна лише шукати, а не переглядати; подальше розміщення посилання на документи було б тут корисним - переважна більшість із цього вже добре і повністю задокументована
Джефф,

6
@ Джефф, є аспекти мого зростання, які були повільними. Використання git - один з них. Я обіцяю, що це те, що я хочу почати робити.
piRSquared

Використання pd.concat(..., levels=[lvl]).groupby(axis=1, level=0).sum()дає інший результат, ніжpd.concat(..., levels=[cats]).groupby(axis=1, level=0).sum() . Ти знаєш чому? У документах сказано лише, що це levelsповинен бути список послідовностей.
unutbu

1
Чудова відповідь, але я думаю, що розділ Passing a dict instead of a listпотребує прикладу з використанням дикту, а не списку.
unutbu

1
@unutbu Я виправив dictприклад, thx. Причиною тому є lvlкатегоріальний покажчик і catsлише перелік. При групуванні за категоріальним типом відсутні категорії заносяться нулями та нулями, де це доречно. Дивіться це
piRSquared
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.