Q1: health_data.loc[:,'Guido']
выбирает один столбец из первого уровня мультииндекса столбца, тогда как health_data.loc[:,['Guido']]
выбирает список столбцов из одного и того же. Я полагаю, что разработчики Pandas могли бы сделать список из 1 элемента особым случаем и исключить избыточное измерение из ответа, но они этого не сделали.
In [6]: health_data.loc[:,'Guido']
Out[6]:
type HR Temp
year visit
2013 1 38.0 35.4
2 29.0 36.9
2014 1 41.0 36.6
2 26.0 36.9
In [7]: health_data.loc[:,['Guido']]
Out[7]:
subject Guido
type HR Temp
year visit
2013 1 38.0 35.4
2 29.0 36.9
2014 1 41.0 36.6
2 26.0 36.9
Q2: случаи 1 и 2 выбирают 1 столбец, сначала в виде списка из 1 элемента, а затем в качестве значения одного столбца (как в случаях 2 и 1 соответственно вашего Q1). Случай 3 более интересен: он выбирает список элементов первого уровня мультииндекса. Поскольку в значениях этих уровней существует только «Bob», он возвращает все столбцы, в которых «Bob» находится на первом уровне
In [29]: health_data.loc[:, [('Bob', 'HR')]]
Out[29]:
subject Bob
type HR
year visit
2013 1 29.0
2 47.0
2014 1 56.0
2 37.0
In [30]: health_data.loc[:, ('Bob', 'HR')]
Out[30]:
year visit
2013 1 29.0
2 47.0
2014 1 56.0
2 37.0
Name: (Bob, HR), dtype: float64
In [31]: health_data.loc[:, ['Bob', 'HR']]
Out[31]:
subject Bob
type HR Temp
year visit
2013 1 29.0 36.5
2 47.0 37.7
2014 1 56.0 38.5
2 37.0 37.3
Q3 это, по сути, повтор Q2: idx['Bob','HR']
оценивается как ('Bob', 'HR')
, который выбирает один столбец из мультииндекса. list(idx['Bob','HR'])
оценивается как ['Bob','HR']
, который выбирает список столбцов с 1-го уровня мультииндекса.
In [18]: health_data.loc[:,[idx['Bob','HR']]]
Out[18]:
subject Bob
type HR
year visit
2013 1 29.0
2 47.0
2014 1 56.0
2 37.0
In [19]: health_data.loc[:,list(idx['Bob','HR'])]
Out[19]:
subject Bob
type HR Temp
year visit
2013 1 29.0 36.5
2 47.0 37.7
2014 1 56.0 38.5
2 37.0 37.3
Поскольку «HR» не существует на 1-м уровне мультииндекса, срез выбирает просто «Bob». Вы можете увидеть разницу более четко, если вы замените «Сью» вместо «HR»:
In [27]: health_data.loc[:,[idx['Bob','Sue']]]
Out[27]:
subject Bob
type Sue
year visit
2013 1 NaN
2 NaN
2014 1 NaN
2 NaN
In [28]: health_data.loc[:,list(idx['Bob','Sue'])]
Out[28]:
subject Bob Sue
type HR Temp HR Temp
year visit
2013 1 29.0 36.5 35.0 36.4
2 47.0 37.7 36.0 36.4
2014 1 56.0 38.5 34.0 37.8
2 37.0 37.3 30.0 36.9
В первом случае мы выбираем столбец со значением мультииндекса ('Bob', 'Sue')
, которого не существует - следовательно, NaNs
. Во втором случае мы выбираем столбцы, которые содержат все значения из списка ['Bob', 'Sue']
на первом уровне мультииндекса. Должен признаться, я застал врасплох, увидев, что кортежи и списки дают разные результаты. Опять же, я полагаю, это решение API ...
Документы покрывают большую часть этого:
https://pandas.pydata.org/pandas-docs/stable/advanced.html#advanced-indexing-with-hierarchical-index
https://pandas.pydata.org/pandas-docs/stable/advanced.html#using-slicers