pandasベース--基本機能
54226 ワード
次のコードのデフォルト:import pandas as pd
このセクションでは、SeriesとDataFrameのデータを操作するための基本的な手段について説明します.
1.1再索引
新しいインデックスに適した新しいオブジェクトを作成するreindexを再インデックスします.reindexを呼び出すと、新しいインデックスに基づいて並べ替えられ、インデックス値が現在存在しない場合は欠落した値が導入されます.
時間シーケンスのような秩序化されたデータの場合、インデックスを再インデックスする際に補間処理が必要になる場合があります.methodオプションを使用すると、この目的を達成できます.
次の表は、使用可能なmethodオプションです.
ffillまたはpad
フォワードフィル(または搬送)値
bfillまたはbackfill
バックフィル(または搬送)値
DataFrameの場合、reindexはインデックス、カラム、または両方を変更できます.シーケンスが1つしか入力されない場合は、ローが再インデックスされます.
次の表はreindex関数の各パラメータと説明です.
パラメータ
説明
index
インデックスとして使用される新しいシーケンスは、Indexインスタンスであってもよいし、他のシーケンス型pythonデータ構造であってもよく、複製がないようにIndexが完全に使用されます.
method
補間(塗りつぶし)方式、具体的には一般的な前の表
fill_value
再インデックス処理中に欠落した値を導入する必要がある場合に使用する代替値
limit
前方または後方充填時の最大充填量
level
MultiIndexの指定したレベルで単純インデックスを一致させない場合は、そのサブセットを選択します.
copy
デフォルトはTrueで、何でもコピーします.そうでなければFalseで、新旧が等しい場合はコピーしません.
1.2指定された軸上のアイテムを破棄する
軸上の1つ以上のアイテムを破棄するには、インデックス配列またはリストが1つあれば完了します.いくつかのデータ整理と集合論理を実行する必要があるため、dropメソッドは指定した軸から指定した値を削除した新しいオブジェクトを返します.
DataFrameの場合、任意の軸のインデックス値を削除できます.
1.3索引、選択、フィルタ
Seriesインデックス(obj[...])の動作はNumPy配列のインデックスに似ていますが、Seriesのインデックス値は整数ではありません.
ラベルを用いたスライス演算は,通常のpythonスライス演算とは異なり,その末端に含まれる.
DataFrameをインデックスすることは、1つ以上のカラムを取得することです.
DataFrameのインデックス・オプションは次の表に示されています.
を選択します.
説明
obj[val]
DataFrameの単一列または列のセットを選択すると、ブール配列(行のフィルタ)、スライス(行のスライス)、ブールデータFrame(条件に応じて値を設定)が便利になります.
reindexメソッド
1つ以上の軸を新しいインデックスに一致させる
xs
ラベルに基づいて1行または1列を選択し、Seriesを返します.
1.4算術演算とデータ配置
pandasは、異なるインデックスのオブジェクトに対して算術演算を行うことができる.オブジェクトを加算するときに、異なるインデックスペアが存在する場合、結果はインデックスペアの並列セットになります.重複していないインデックスにNaN値が導入され、欠落した値が演算中に伝播します.
DataFrameの場合、行と列の位置合わせが同時に行われます.これらを加算すると、新しいデータFrameが返されます.インデックスと元の2つのデータFrameの並列セットが表示されます.
1.5算術メソッドに値を入力する
異なるインデックスのオブジェクトを算術演算する場合、あるオブジェクトの軸ラベルが別のオブジェクトに見つからない場合、特殊な値を入力します.
柔軟な算術方法を以下の表に示します.
方法
説明
add
加算(+)の方法
sub
減算(-)の方法
div
除算(/)の方法
mul
乗算(*)の方法
1.6 DataFrameとSeriesの演算
DATaFrameとSeriesの演算は明確に規定されている.たとえば、2 D配列とその行の差を計算します.
DataFrameとSeriesの間の演算では、SeriesのインデックスがDataFrameの列に一致し、行に沿って下にブロードキャストされます.
インデックス値がDataFrameのカラムまたはSeriesのインデックスで見つからない場合、演算に参加する2つのオブジェクトが再インデックスされ、パラレルセットが作成されます.
行に一致し、列にブロードキャストする場合は、算術演算メソッドを使用する必要があります.
1.7関数の適用とマッピング
NumPyのufuncs(要素レベル配列法)はpandasオブジェクトの操作にも使用できます.
別の一般的な操作では、各列または行によって形成される1次元配列に関数を適用します.この機能は、DataFrameのapplyメソッドで実現できます.
スカラー値に加えてapplyに渡される関数は、複数の値からなるSeriesを返すこともできます.
要素レベルのpython関数も使用できます.例えばframeの各浮動小数点値のフォーマット文字列を求め、applymapを使用すればよい.
1.8ソートとランキング
(1)並べ替え
条件に基づいてデータセットをソートすることも重要な組み込み演算です.行または列のインデックスをソートするには、sort_indexメソッドを使用します.ソートされた新しいオブジェクトを返します.
DataFrameでは、いずれかの軸のインデックスに基づいてソートできます.
(2)ランキング
ランキングはソートと密接に関連しており、1から配列内の有効なデータの数までランキング値が増加します.rankメソッドを使用し、rankは「各グループに平均ランキングを割り当てる」ことでレベル関係を破壊します.
ここはちょっとわかりにくいですが、下図のように理解できます.
元のデータ
人為的なランキング
methodパラメータ値
索引
値
average
min
max
first
0
7
6
6.5
6
7
6
1
-5
1
1
1
1
1
2
7
7
6.5
6
7
7
3
4
4
4.5
4
5
4
4
2
3
3
3
3
3
5
0
2
2
2
2
2
6
4
5
4.5
4
5
5
methodパラメータの説明.
method
説明
‘average’
デフォルトでは、等しいグループに平均順位を割り当てます
‘min’
グループ全体の最小順位の使用
‘max’
グループ全体の最大順位の使用
‘first’
元のデータに値が表示される順序で順位を割り当てる
例:
DataFrameでは、ランキングを行または列で計算できます.
1.9重複する値を持つ軸インデックス
pandasは軸ラベルの一意性を強制しない.重複する値を持つインデックスでは、データ選択の型ビットが異なります.インデックスが複数の値に対応する場合、Seriesが返されます.一方、単一の値に対応する場合は、スカラー値が返されます.DataFrameもそうです.
このセクションでは、SeriesとDataFrameのデータを操作するための基本的な手段について説明します.
1.1再索引
新しいインデックスに適した新しいオブジェクトを作成するreindexを再インデックスします.reindexを呼び出すと、新しいインデックスに基づいて並べ替えられ、インデックス値が現在存在しない場合は欠落した値が導入されます.
1 >>> obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
2 >>> obj
3 d 4.5
4 b 7.2
5 a -5.3
6 c 3.6
7 dtype: float64
8 >>> obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
9 >>> obj2
10 a -5.3
11 b 7.2
12 c 3.6
13 d 4.5
14 e NaN
15 dtype: float64
16 >>> obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
17 a -5.3
18 b 7.2
19 c 3.6
20 d 4.5
21 e 0.0
22 dtype: float64
23 >>>
時間シーケンスのような秩序化されたデータの場合、インデックスを再インデックスする際に補間処理が必要になる場合があります.methodオプションを使用すると、この目的を達成できます.
1 >>> obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
2 >>> obj3.reindex(range(6), method='ffill')
3 0 blue
4 1 blue
5 2 purple
6 3 purple
7 4 yellow
8 5 yellow
9 dtype: object
次の表は、使用可能なmethodオプションです.
ffillまたはpad
フォワードフィル(または搬送)値
bfillまたはbackfill
バックフィル(または搬送)値
DataFrameの場合、reindexはインデックス、カラム、または両方を変更できます.シーケンスが1つしか入力されない場合は、ローが再インデックスされます.
1 >>> frame = pd.DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio',
2 'Texas', 'California'])
3 >>> frame
4 Ohio Texas California
5 a 0 1 2
6 c 3 4 5
7 d 6 7 8
8 >>> frame2 = frame.reindex(['a', 'b', 'c', 'd']) #
9 >>> frame2
10 Ohio Texas California
11 a 0.0 1.0 2.0
12 b NaN NaN NaN
13 c 3.0 4.0 5.0
14 d 6.0 7.0 8.0
15 >>> states = ['Texas', 'Utah', 'California']
16 >>> frame.reindex(columns=states) # columns
17 Texas Utah California
18 a 1 NaN 2
19 c 4 NaN 5
20 d 7 NaN 8
21 >>> frame.reindex(index=['a', 'b', 'c', 'd'], method='ffill')
22 Ohio Texas California
23 a 0 1 2
24 b 0 1 2
25 c 3 4 5
26 d 6 7 8
次の表はreindex関数の各パラメータと説明です.
パラメータ
説明
index
インデックスとして使用される新しいシーケンスは、Indexインスタンスであってもよいし、他のシーケンス型pythonデータ構造であってもよく、複製がないようにIndexが完全に使用されます.
method
補間(塗りつぶし)方式、具体的には一般的な前の表
fill_value
再インデックス処理中に欠落した値を導入する必要がある場合に使用する代替値
limit
前方または後方充填時の最大充填量
level
MultiIndexの指定したレベルで単純インデックスを一致させない場合は、そのサブセットを選択します.
copy
デフォルトはTrueで、何でもコピーします.そうでなければFalseで、新旧が等しい場合はコピーしません.
1.2指定された軸上のアイテムを破棄する
軸上の1つ以上のアイテムを破棄するには、インデックス配列またはリストが1つあれば完了します.いくつかのデータ整理と集合論理を実行する必要があるため、dropメソッドは指定した軸から指定した値を削除した新しいオブジェクトを返します.
1 >>> obj = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e'])
2 >>> new_obj = obj.drop('c')
3 >>> new_obj
4 a 0
5 b 1
6 d 3
7 e 4
8 dtype: int32
9 >>> obj.drop(['d', 'c'])
10 a 0
11 b 1
12 e 4
13 dtype: int32
DataFrameの場合、任意の軸のインデックス値を削除できます.
1 >>> data = pd.DataFrame(np.arange(16).reshape((4, 4)), index=['Oh', 'Co', 'Ut', 'New'], columns=['one', 'two', 'three', 'four'])
2 >>> data
3 one two three four
4 Oh 0 1 2 3
5 Co 4 5 6 7
6 Ut 8 9 10 11
7 New 12 13 14 15
8 >>> data.drop('two', axis=1)
9 one three four
10 Oh 0 2 3
11 Co 4 6 7
12 Ut 8 10 11
13 New 12 14 15
14 >>> data.drop(['two', 'four'], axis=1)
15 one three
16 Oh 0 2
17 Co 4 6
18 Ut 8 10
19 New 12 14
1.3索引、選択、フィルタ
Seriesインデックス(obj[...])の動作はNumPy配列のインデックスに似ていますが、Seriesのインデックス値は整数ではありません.
1 >>> obj = pd.Series(np.arange(4), index=['a', 'b', 'c', 'd'])
2 >>> obj['b']
3 1
4 >>> obj[1]
5 1
6 >>> obj[2:4]
7 c 2
8 d 3
9 dtype: int32
10 >>> obj[['b', 'a', 'd']]
11 b 1
12 a 0
13 d 3
14 dtype: int32
15 >>> obj[[1, 3]]
16 b 1
17 d 3
18 dtype: int32
19 >>> obj[obj < 2]
20 a 0
21 b 1
22 dtype: int32
23 >>>
ラベルを用いたスライス演算は,通常のpythonスライス演算とは異なり,その末端に含まれる.
1 >>> obj
2 a 0
3 b 1
4 c 2
5 d 3
6 dtype: int32
7 >>> obj['b':'d']
8 b 1
9 c 2
10 d 3
11 dtype: int32
12 >>> obj['b':'d'] = 5 #
13 >>> obj
14 a 0
15 b 5
16 c 5
17 d 5
18 dtype: int32
DataFrameをインデックスすることは、1つ以上のカラムを取得することです.
1 >>> data
2 one two three four
3 Oh 0 1 2 3
4 Co 4 5 6 7
5 Ut 8 9 10 11
6 New 12 13 14 15
7 >>> data['two']
8 Oh 1
9 Co 5
10 Ut 9
11 New 13
12 Name: two, dtype: int32
13 >>> data[['three', 'one']]
14 three one
15 Oh 2 0
16 Co 6 4
17 Ut 10 8
18 New 14 12
19 >>> data[:2] #
20 one two three four
21 Oh 0 1 2 3
22 Co 4 5 6 7
23 >>> data[data['three'] > 5] #
24 one two three four
25 Co 4 5 6 7
26 Ut 8 9 10 11
27 New 12 13 14 15
28 >>> data < 5
29 one two three four
30 Oh True True True True
31 Co True False False False
32 Ut False False False False
33 New False False False False
34 >>> data[data < 5] = 0 #
35 >>> data
36 one two three four
37 Oh 0 0 0 0
38 Co 0 5 6 7
39 Ut 8 9 10 11
40 New 12 13 14 15
41 >>>
DataFrameのインデックス・オプションは次の表に示されています.
を選択します.
説明
obj[val]
DataFrameの単一列または列のセットを選択すると、ブール配列(行のフィルタ)、スライス(行のスライス)、ブールデータFrame(条件に応じて値を設定)が便利になります.
reindexメソッド
1つ以上の軸を新しいインデックスに一致させる
xs
ラベルに基づいて1行または1列を選択し、Seriesを返します.
1.4算術演算とデータ配置
pandasは、異なるインデックスのオブジェクトに対して算術演算を行うことができる.オブジェクトを加算するときに、異なるインデックスペアが存在する場合、結果はインデックスペアの並列セットになります.重複していないインデックスにNaN値が導入され、欠落した値が演算中に伝播します.
1 >>> s1 = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
2 >>> s2 = pd.Series([5, 6, 7, 8], index = ['a', 'c', 'e', 'f'])
3 >>> s1 + s2 #
4 a 6.0
5 b NaN
6 c 9.0
7 d NaN
8 e NaN
9 f NaN
10 dtype: float64
11 >>>
DataFrameの場合、行と列の位置合わせが同時に行われます.これらを加算すると、新しいデータFrameが返されます.インデックスと元の2つのデータFrameの並列セットが表示されます.
1 >>> df1 = pd.DataFrame(np.arange(9).reshape((3, 3)), columns=list('bcd'), index=['one', 'two',
2 'three'])
3 >>> df2 = pd.DataFrame(np.arange(4).reshape((2, 2)), columns=list('be'), index=['two', 'four'])
4 >>> df1
5 b c d
6 one 0 1 2
7 two 3 4 5
8 three 6 7 8
9 >>> df2
10 b e
11 two 0 1
12 four 2 3
13 >>> df1 + df2 #
14 b c d e
15 four NaN NaN NaN NaN
16 one NaN NaN NaN NaN
17 three NaN NaN NaN NaN
18 two 3.0 NaN NaN NaN
19 >>>
1.5算術メソッドに値を入力する
異なるインデックスのオブジェクトを算術演算する場合、あるオブジェクトの軸ラベルが別のオブジェクトに見つからない場合、特殊な値を入力します.
1 >>> df1
2 b c d
3 one 0 1 2
4 two 3 4 5
5 three 6 7 8
6 >>> df2
7 b e
8 two 0 1
9 four 2 3
10 >>> df1.add(df2, fill_value=0)
11 b c d e
12 four 2.0 NaN NaN 3.0
13 one 0.0 1.0 2.0 NaN
14 three 6.0 7.0 8.0 NaN
15 two 3.0 4.0 5.0 1.0
16 >>> df1.add(df2, fill_value=1)
17 b c d e
18 four 3.0 NaN NaN 4.0
19 one 1.0 2.0 3.0 NaN
20 three 7.0 8.0 9.0 NaN
21 two 3.0 5.0 6.0 2.0
22 >>> df1.reindex(columns=df2.columns, fill_value=0)
23 b e
24 one 0 0
25 two 3 0
26 three 6 0
柔軟な算術方法を以下の表に示します.
方法
説明
add
加算(+)の方法
sub
減算(-)の方法
div
除算(/)の方法
mul
乗算(*)の方法
1.6 DataFrameとSeriesの演算
DATaFrameとSeriesの演算は明確に規定されている.たとえば、2 D配列とその行の差を計算します.
1 >>> arr = np.arange(12).reshape((3, 4))
2 >>> arr
3 array([[ 0, 1, 2, 3],
4 [ 4, 5, 6, 7],
5 [ 8, 9, 10, 11]])
6 >>> arr[0]
7 array([0, 1, 2, 3])
8 >>> arr - arr[0] #
9 array([[0, 0, 0, 0],
10 [4, 4, 4, 4],
11 [8, 8, 8, 8]])
DataFrameとSeriesの間の演算では、SeriesのインデックスがDataFrameの列に一致し、行に沿って下にブロードキャストされます.
1 >>> frame = pd.DataFrame(np.arange(12).reshape((4, 3)), columns=list('bde'), index=['Ut', 'Oh', 'Te', 'Or'])
2 >>> frame
3 b d e
4 Ut 0 1 2
5 Oh 3 4 5
6 Te 6 7 8
7 Or 9 10 11
8 >>> series = pd.Series(np.arange(3), index=['b', 'd', 'e'])
9 >>> series
10 b 0
11 d 1
12 e 2
13 dtype: int32
14 >>> frame - series
15 b d e
16 Ut 0 0 0
17 Oh 3 3 3
18 Te 6 6 6
19 Or 9 9 9
20 >>>
インデックス値がDataFrameのカラムまたはSeriesのインデックスで見つからない場合、演算に参加する2つのオブジェクトが再インデックスされ、パラレルセットが作成されます.
1 >>> series2 = pd.Series(range(3), index=list('bef'))
2 >>> series2
3 b 0
4 e 1
5 f 2
6 dtype: int64
7 >>> frame
8 b d e
9 Ut 0 1 2
10 Oh 3 4 5
11 Te 6 7 8
12 Or 9 10 11
13 >>> frame + series2
14 b d e f
15 Ut 0.0 NaN 3.0 NaN
16 Oh 3.0 NaN 6.0 NaN
17 Te 6.0 NaN 9.0 NaN
18 Or 9.0 NaN 12.0 NaN
19 >>>
行に一致し、列にブロードキャストする場合は、算術演算メソッドを使用する必要があります.
1 >>> series3 = frame['d']
2 >>> frame
3 b d e
4 Ut 0 1 2
5 Oh 3 4 5
6 Te 6 7 8
7 Or 9 10 11
8 >>> series3
9 Ut 1
10 Oh 4
11 Te 7
12 Or 10
13 Name: d, dtype: int32
14 >>> frame.sub(series3, axis=0)
15 b d e
16 Ut -1 0 1
17 Oh -1 0 1
18 Te -1 0 1
19 Or -1 0 1
1.7関数の適用とマッピング
NumPyのufuncs(要素レベル配列法)はpandasオブジェクトの操作にも使用できます.
1 >>> frame
2 b d e
3 Ut 0 -3 2
4 Oh 3 -3 5
5 Te 6 -3 8
6 Or 9 -3 11
7 >>> np.abs(frame)
8 b d e
9 Ut 0 3 2
10 Oh 3 3 5
11 Te 6 3 8
12 Or 9 3 11
別の一般的な操作では、各列または行によって形成される1次元配列に関数を適用します.この機能は、DataFrameのapplyメソッドで実現できます.
1 >>> f = lambda x: x.max() - x.min()
2 >>> frame
3 b d e
4 Ut 0 -3 2
5 Oh 3 -3 5
6 Te 6 -3 8
7 Or 9 -3 11
8 >>> frame.apply(f)
9 b 9
10 d 0
11 e 9
12 dtype: int64
13 >>> frame.apply(f, axis=1)
14 Ut 5
15 Oh 8
16 Te 11
17 Or 14
18 dtype: int64
19 >>>
スカラー値に加えてapplyに渡される関数は、複数の値からなるSeriesを返すこともできます.
1 >>> def f(x):
2 ... return pd.Series([x.min(), x.max()], index=['min', 'max'])
3 ...
4 >>> frame
5 b d e
6 Ut 0 -3 2
7 Oh 3 -3 5
8 Te 6 -3 8
9 Or 9 -3 11
10 >>> frame.apply(f)
11 b d e
12 min 0 -3 2
13 max 9 -3 11
14 >>>
要素レベルのpython関数も使用できます.例えばframeの各浮動小数点値のフォーマット文字列を求め、applymapを使用すればよい.
1 >>> format = lambda x: '%.2f' % x
2 >>> frame.applymap(format)
3 b d e
4 Ut 0.00 -3.00 2.00
5 Oh 3.00 -3.00 5.00
6 Te 6.00 -3.00 8.00
7 Or 9.00 -3.00 11.00
1.8ソートとランキング
(1)並べ替え
条件に基づいてデータセットをソートすることも重要な組み込み演算です.行または列のインデックスをソートするには、sort_indexメソッドを使用します.ソートされた新しいオブジェクトを返します.
1 >>> obj = pd.Series(range(4), index=['d', 'e', 'b', 'c'])
2 >>> obj.sort_index()
3 b 2
4 c 3
5 d 0
6 e 1
7 dtype: int64
DataFrameでは、いずれかの軸のインデックスに基づいてソートできます.
1 >>> frame = pd.DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'e', 'b', 'c'])
2 >>> frame.sort_index()
3 d e b c
4 one 4 5 6 7
5 three 0 1 2 3
6 >>> frame.sort_index(axis=1) # 1
7 b c d e
8 three 2 3 0 1
9 one 6 7 4 5
10 >>> frame.sort_index(axis=1, ascending=False) # ,
11 e d c b
12 three 1 0 3 2
13 one 5 4 7 6
14 >>>
(2)ランキング
ランキングはソートと密接に関連しており、1から配列内の有効なデータの数までランキング値が増加します.rankメソッドを使用し、rankは「各グループに平均ランキングを割り当てる」ことでレベル関係を破壊します.
ここはちょっとわかりにくいですが、下図のように理解できます.
元のデータ
人為的なランキング
methodパラメータ値
索引
値
average
min
max
first
0
7
6
6.5
6
7
6
1
-5
1
1
1
1
1
2
7
7
6.5
6
7
7
3
4
4
4.5
4
5
4
4
2
3
3
3
3
3
5
0
2
2
2
2
2
6
4
5
4.5
4
5
5
methodパラメータの説明.
method
説明
‘average’
デフォルトでは、等しいグループに平均順位を割り当てます
‘min’
グループ全体の最小順位の使用
‘max’
グループ全体の最大順位の使用
‘first’
元のデータに値が表示される順序で順位を割り当てる
例:
1 >>> obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
2 >>> obj.rank()
3 0 6.5
4 1 1.0
5 2 6.5
6 3 4.5
7 4 3.0
8 5 2.0
9 6 4.5
10 dtype: float64
11 >>> obj
12 0 7
13 1 -5
14 2 7
15 3 4
16 4 2
17 5 0
18 6 4
19 dtype: int64
20 >>> obj.rank(method='first') #
21 0 6.0
22 1 1.0
23 2 7.0
24 3 4.0
25 4 3.0
26 5 2.0
27 6 5.0
28 dtype: float64
29 >>> obj.rank(ascending=False, method='max') #
30 0 2.0
31 1 7.0
32 2 2.0
33 3 4.0
34 4 5.0
35 5 6.0
36 6 4.0
37 dtype: float64
DataFrameでは、ランキングを行または列で計算できます.
1 >>> frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1], 'c': [-2, 5, 8, -2.5]})
2 >>> frame
3 b a c
4 0 4.3 0 -2.0
5 1 7.0 1 5.0
6 2 -3.0 0 8.0
7 3 2.0 1 -2.5
8 >>> frame.rank(axis=1)
9 b a c
10 0 3.0 2.0 1.0
11 1 3.0 1.0 2.0
12 2 1.0 2.0 3.0
13 3 3.0 2.0 1.0
1.9重複する値を持つ軸インデックス
pandasは軸ラベルの一意性を強制しない.重複する値を持つインデックスでは、データ選択の型ビットが異なります.インデックスが複数の値に対応する場合、Seriesが返されます.一方、単一の値に対応する場合は、スカラー値が返されます.DataFrameもそうです.
1 >>> obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
2 >>> obj
3 a 0
4 a 1
5 b 2
6 b 3
7 c 4
8 dtype: int64
9 >>> obj.index.is_unique
10 False
11 >>> obj['a']
12 a 0
13 a 1
14 dtype: int64
15 >>> obj['c']
16 4