pandas クイズ

----
# はじめに

----
# 概要
pandasを使っていたハマったことや、ハマりそうなことをクイズにしました。

問題の多くは2択です。直観で答えてみてください。

:::note info
2024/04/19に社内でpandasクイズを実施しました。
:::

----

## 動作環境
以下の環境で動作確認しました。

* pandas 2.2.2
* numpy 1.26.4
* Python 3.12.1

事前にIPythonで以下をimportしています。

```
In [1]: import pandas as pd
In [2]: import numpy as np
```

----
## 問題文の例（出力結果を答える）
IPythonで実行したときに、どのような結果になるかを選択してください。
問題となる実行文は、`In [?]`で表します。
出力結果の選択肢は`Out[1]`, `Out[2]`のように表します。

```
In [?]: np.inf - np.inf

Out[1]: nan

Out[2]: 0.0

Out[3]: 
raise Error
```

1, 2, 3のいずれかの番号を選択してください。

なお、回答は1です。

----
## 問題文の例（実行文を答える）
ある実行文に対する出力結果を`Out[?]`で表します。
ある実行文の選択肢を、`In[1]`, `In[2]`のように表します。

```
In [1]: np.inf + np.inf

In [2]: np.inf - np.inf

In [3]: np.inf * np.inf

In [4]: np.inf / np.inf

Out[?]: nan
```

適切な実行文を1, 2, 3, 4の番号からすべてを選択してください。

なお、回答は2と4です。


------

# データの取得に関するクイズ


-----
### 問01: Seriesに対して`[]`でアクセス

```
In [372]: s1 = pd.Series(["a","b"])

In [373]: s1
Out[373]:
0    a
1    b
dtype: object

# `[0]`は0番目の要素が返る
In [374]: s1[0]
Out[374]: 'a'
```

ですが...

```
# indexがs1と異なる場合
In [375]: s2 = pd.Series(["a","b"], index=[1,0])

In [376]: s2
Out[376]:
1    a
0    b
dtype: object

In [?]: s2[0]

# 0番目の要素が返る？
Out[1]: 'a'

# indexが0である要素が返る？
Out[2]: 'b'
```

適切なOuputを1つ選択してください。

-----

### 答: 2

indexが0である要素が返ります。

```
In [377]: s2[0]
Out[377]: 'b'
```




----
### 問02:  Seriesに対して`[]`でアクセス Part2

```
In [559]: s3 = pd.Series(["a","b"], index=["x","y"])

In [560]: s3
Out[560]:
x    a
y    b
dtype: object

In [?]: s3[0]

# 0番目の要素が返る？
Out[1]: 'a'

# indexに0は存在しないからエラーが発生する？
Out[2]:
raise KeyError
```


適切なOutputを1つ選択してください。

------

### 答: 1

0番目の要素が返ります。
ただし`FutureWarning`が発生します。将来のバージョンではindexが0である要素を返すようなので、エラーが発生すると思います。

```
In [561]: s3[0]
<ipython-input-561-e48481fcb92e>:1: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  s3[0]
```





-----
### 問03: Seriesに対して`.loc[]`にスライスを指定したとき

```
In [391]: s1 = pd.Series([4,5,6], index=["a","b","c"])

In [?]: s1.loc["a":"b"]
# index "b"は含まれる？
Out[1]:
a    4
b    5
dtype: int64

# index "b"は含まれない？
Out[2]:
a    4
dtype: int64
```

----
### 答: 1

スライスの終了位置は含まれます。

```
In [412]: s1.loc["a":"b"]
Out[412]:
a    4
b    5
dtype: int64
```


----
### 問04: Seriesに対して`.loc[]`にスライスを指定する Part2


```
# indexに整数を指定
In [417]: s1 = pd.Series(["a","b","c"], index=[1,3,5])

In [418]: s1.loc[1:5]
Out[418]:
1    a
3    b
5    c
dtype: object
```

```
# indexに存在しない0を開始,6は終了に指定する
In [?]: s1.loc[0:6]
Out[1]:
1    a
3    b
5    c
dtype: object

Out[2]:
raise KeyError
````

適切なOutputを1つ選択してください。

----
### 答: 1

>If at least one of the two is absent, but the index is sorted, and can be compared against start and stop labels, then slicing will still work as expected, by selecting labels which rank between the two [^21]

[^21]: https://pandas.pydata.org/docs/user_guide/indexing.html#slicing-with-labels

※ "at least one of the two is absent"とあるが、両方存在しなくても期待通り動くのはなぜ？


```
# indexがソートされていない場合
In [445]: s = pd.Series(["a","b","c"], index=[5,1,3])

In [446]: s.loc[0:6]
...
KeyError: 0
```

>However, if at least one of the two is absent and the index is not sorted, an error will be raised (since doing otherwise would be computationally expensive, as well as potentially ambiguous for mixed type indexes).  [^22]

[^22]: https://pandas.pydata.org/docs/user_guide/indexing.html#slicing-with-labels





----

### 問05: Seriesに対して`[]`にスライスを指定する


```
In [391]: s1 = pd.Series([4,5,6], index=["a","b","c"])

In [400]: s1
Out[400]:
a    4
b    5
c    6
dtype: int64

In [?]: s1[1:]

# indexに1は存在しないからエラーになる？
Out[1]:
raise KeyError

# 1番目以降の要素が返る？
Out[2]:
b    5
c    6
dtype: int64
```

適切なOutputを一つ選択してください。

-----
### 答: 2

`[1:]`は、1番目以降の要素が返ります。

```
In [402]: s1[1:]
Out[402]:
b    5
c    6
dtype: int64
```

なお、スライスでindexを指定することもできます。

```
In [471]: s1["b":]
Out[471]:
b    5
c    6
dtype: int64
```

Seriesに対して`[]`を指定したときの挙動は、`__getitem__()`で定義されています。

https://github.com/pandas-dev/pandas/blob/d9cdd2ee5a58015ef6f4d15c7226110c9aab8140/pandas/core/series.py#L1095

`__getitem__()`の中では、以下のような判定を行って処理しています。

* `key_is_scalar` -> ` self._get_value(key)`
* `is_integer(key) and self.index._should_fallback_to_positional` -> `self._values[key]`
* `isinstance(key, slice)` -> `self._getitem_slice(key)`




------
### 問06: DataFrameに対して`[]`でアクセスする

```
# columnとindexを同じにする
In [451]: df = pd.DataFrame({"a":[1,2], "b":[3,4]}, index=["a","b"])

In [452]: df
Out[452]:
   a  b
a  1  3
b  2  4

In [?]: df["a"]
# column "a"が返る？
Out[1]:
a    1
b    2
Name: a, dtype: int64

# index "a"が返る？
Out[2]:
a    1
b    3
Name: a, dtype: int64
```

適切なOutputを1つ選択してください。



------
### 答: 1

column `a`の情報が返ります。

```

In [473]: df["a"]
Out[473]:
a    1
b    2
Name: a, dtype: int64
```


----
### 問07: DataFrameに対して`[]`にスライスを指定する

```
In [451]: df = pd.DataFrame({"a":[1,2], "b":[3,4]}, index=["a","b"])

In [452]: df
Out[452]:
   a  b
a  1  3
b  2  4

In [?]: df["b":]
# column "b"の情報が返る？
Out[1]:
   b
a  3
b  4

# index "b"の情報が返る？
Out[2]:
   a  b
b  2  4
```

適切なOutputを1つ選択してください。


----
### 答: 2

DataFrameに対して`[]`にスライスを指定すると、indexに紐づく情報が返ります。

```
In [474]: df["b":]
Out[474]:
   a  b
b  2  4
```

----
### 問08: Seriesを`for in`でループする


```
In [460]: s = pd.Series([1,2], index=["a","b"])

In [461]: s
Out[461]:
a    1
b    2
dtype: int64

In [?]: [e for e in s]

# 値が返る？ list-like?
Out[1]: [1, 2]

# indexが返る？ dict-like?
Out[2]: ["a", "b"]
```

適切なOutputを1つ選択してください。


----
### 答: 1

Seriesを`for-in`ループで回すと値が返ります。

```
In [467]:  [e for e in s]
Out[467]: [1, 2]
```

`Series`はdict-likeでもありlist-likeです。


------
# Seriesオブジェクトの生成に関するクイズ

------
### 問11: `Series()`で`index`引数を指定した場合

```
# 事前知識
In [15]: pd.Series(data={"a":1.0, "b":2.0})
Out[15]:
a    1.0
b    2.0
dtype: float64
```

```
In [?]: pd.Series(data={"a":1.0, "b":2.0}, index=["a","c"])

# `index`優先
Out[1]:
a    1.0
c    NaN
dtype: float64

# `data`優先
Out[2]:
a    1.0
b    2.0
dtype: float64

# `data`と`index`のunion
Out[3]:
a    1.0
b    2.0
c    NaN
dtype: float64
```

適切なOutputを選択してください。

------------
### 答: 1

```
In [475]: pd.Series(data={"a":1.0, "b":2.0}, index=["a","c"])
Out[475]:
a    1.0
c    NaN
dtype: float64
```

>If an index is passed, the values in data corresponding to the labels in the index will be pulled out. [^2]

[^2]: https://pandas.pydata.org/docs/user_guide/dsintro.html#series-is-dict-like



------
### 問12: `Series()`で`index`引数を指定した場合 Part2

```
In [19]: pd.Series([1.0, 2.0], index=["a", "b"])
Out[19]:
a    1.0
b    2.0
dtype: float64
```

```
# dataのlengthとindexの長さ異なる場合
In [?]: pd.Series([1.0, 2.0], index=["a"])

Out[1]:
a    1.0
dtype: float64

Out[2]: 
raise ValueError
```
適切なOutputを選択してください。

------
### 答: 2

```
In [475]: pd.Series(data={"a":1.0, "b":2.0}, index=["a","c"])
Out[475]:
a    1.0
c    NaN
dtype: float64

In [476]: pd.Series([1.0, 2.0], index=["a"])
--------------------------------------------------------------
ValueError: Length of values (2) does not match length of index (1)
```


>If data is an ndarray, index must be the same length as data. [^3]

`index`引数で指定した値が優先される訳ではないようです。


[^3]: https://pandas.pydata.org/docs/user_guide/dsintro.html#series

-----
### 問13: `Series`同士の加算

```
In [475]: s = pd.Series([1,2], index=["a","b"])

In [480]: s1 = s.iloc[0:1]

In [481]: s1
Out[481]:
a    1
dtype: int64

In [482]: s2 = s.iloc[1:]

In [483]: s2
Out[483]:
b    2
dtype: int64

In [?]: s1 + s2

# 同じindexのものがあれば加算されるが、同じindexはないのでindexをunionしたものと同じになる？
Out[1]:
a   1
b   2
dtype: int64

# 同じindexのもの同士で加算するが、同じindexがないのでNaNとの加算になる？
Out[2]:
a   NaN
b   NaN
dtype: float64

# 両方に存在するindexは存在しないから、空のSereisになる？
Out[3]: Series([], dtype: float64)
```

適切なOutputを選択してください。

-----
### 答: 2

```
In [486]: s1 + s2
Out[486]:
a   NaN
b   NaN
dtype: float64
```

>The result of an operation between unaligned Series will have the union of the indexes involved. If a label is not found in one Series or the other, the result will be marked as missing NaN. [^1]

[^1]: https://pandas.pydata.org/docs/user_guide/dsintro.html#vectorized-operations-and-label-alignment-with-series



-----
# DataFrameオブジェクトの生成に関するクイズ

----
### 問21: 異なるnamedtupleで構成されたlistを`pd.DataFrame()`に渡す

```
In [32]: from collections import namedtuple
In [33]: Point = namedtuple("Point", "x y")
In [34]: Point3D = namedtuple("Point3D", "x y z")
```

```
# 先頭の要素が`Point3D`
In [?]: pd.DataFrame([Point3D(0, 0, 0),  Point(0, 0)])
Out[1]:
   x  y    z
0  0  0  0.0
1  0  0  NaN

Out[2]:
raise ValueError
```

```
# 先頭の要素が`Point`
In [?]: pd.DataFrame([Point(0, 0), Point3D(0, 0, 0)])
Out[3]:
   x  y    z
0  0  0  NaN
1  0  0  0.0

Out[4]:
raise ValueError
```

適切なOutputをすべて選択してください。

---
### 答: 1, 4


```
In [490]: pd.DataFrame([Point3D(0, 0, 0),  Point(0, 0)])
Out[490]:
   x  y    z
0  0  0  0.0
1  0  0  NaN


In [38]: pd.DataFrame([Point(0, 0), Point3D(0, 0, 0)])
----
ValueError: 2 columns passed, passed data had 3 columns
```

>The field names of the first namedtuple in the list determine the columns of the DataFrame. The remaining namedtuples (or tuples) are simply unpacked and their values are fed into the rows of the DataFrame. If any of those tuples is shorter than the first namedtuple then the later columns in the corresponding row are marked as missing values. If any are longer than the first namedtuple, a ValueError is raised. [^4]

[^4]: https://pandas.pydata.org/docs/user_guide/dsintro.html#from-a-list-of-namedtuples

dictのlistを渡せば`ValueError`は発生しません。

```
In [10]: pd.DataFrame([{"x":0, "y":0}, {"x":0, "y":0, "z":0}])
Out[10]:
   x  y    z
0  0  0  NaN
1  0  0  0.0
```


-----
### 問22: DataFrameに対して`Series`を代入して列を追加

```
In [17]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [18]: df
Out[18]:
     x
a  1.0
b  2.0

In [19]: s = pd.Series([11.0, 13.0], index=["a","c"])

In [20]: s
Out[20]:
a    11.0
c    13.0
dtype: float64

# column 'y'を追加
In [21]: df["y"] = s

In [?]: df

# `df.index`と`s.index`のunionが新しいindexになる
Out[1]:
     x      y
a    1   11.0
b    2    NaN
c  NaN   13.0

# `df`に存在しないindexは無視される
Out[2]:
     x     y
a  1.0  11.0
b  2.0   NaN
```

適切なOutputを1つ選択してください。


-----

### 答: 2

```
In [532]: s = pd.Series([11.0, 13.0], index=["a","c"])

In [533]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [534]: df["y"] = s

In [535]: df
Out[535]:
     x     y
a  1.0  11.0
b  2.0   NaN
```

>When inserting a Series that does not have the same index as the DataFrame, it will be conformed to the DataFrame’s index: [^5]

[^5]: https://pandas.pydata.org/docs/user_guide/dsintro.html#column-selection-addition-deletion

DataFrameへの代入で、DataFrameのindexは変化しない（はず）ようにみえます。


-----

### 問23: DataFrameに対して`list`を代入して列を追加


```
In [29]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [30]: df
Out[30]:
     x
a  1.0
b  2.0

# column 'y' を追加
In [31]: df["y"] = [11.0, 12.0]

In [?]: df["y"]

# listにはindexが存在しないから、df.indexに対応しないのでY列はNaN ？
Out[1]:
a    NaN
b    NaN
Name: y, dtype: float64

# よしなに追加できるはず？
Out[2]:
a    11.0
b    12.0
Name: y, dtype: float64
```

適切なOutputを1つ選択してください。

----

### 答: 2


```
In [536]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [537]: df["y"] = [11.0, 12.0]

In [538]: df["y"]
Out[538]:
a    11.0
b    12.0
Name: y, dtype: float64
```

-----

### 問24: DataFrameに対して`Series`を代入して列を追加 Part2

```
In [29]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [30]: df
Out[30]:
     x
a  1.0
b  2.0


In [30]: s = pd.Series([11.0, 12.0])

In [31]: s
Out[31]:
0    11.0
1    12.0
dtype: float64

# column 'y'を追加
In [32]: df["y"] = s

In [?]: df["y"]

# Seriesのindexはdf.indexに対応しないのでY列はNaN？
Out[1]:
a   NaN
b   NaN
Name: y, dtype: float64

# よしなに追加できるはず？
Out[2]:
a    11.0
b    12.0
Name: y, dtype: float64
```

適切なOutputを1つ選択してください。

-----

### 答: 1



```
In [544]: df = pd.DataFrame({"x":[1.0,2.0]}, index=["a","b"])

In [546]: s = pd.Series([11.0, 12.0])

In [547]: df["y"] = s

In [548]: df["y"]
Out[548]:
a   NaN
b   NaN
Name: y, dtype: float64
```


------
### 問25: `DataFrame`と`Series`の加算

```
In [41]: df = pd.DataFrame([[1,2],[3,4]])

In [42]: df
Out[42]:
   0  1
0  1  2
1  3  4

In [43]: s = pd.Series([10,20])

In [44]: s
Out[44]:
0    10
1    20
dtype: int64


In [?]: df + s

# 加算結果は、SeriesのindexとDataFrameのcolumnが対応している？
Out[1]:
    0   1
0  11  22
1  13  24

# 加算結果は、SeriesのindexとDataFrameのindexが対応している？
Out[2]:
    0   1
0  11  12
1  23  24
```

適切なOutputを1つ選択してください。

-----

### 答: 1

加算結果は、SeriesのindexとDataFrameのcolumnが対応しています。

```
In [502]: df + s
Out[502]:
    0   1
0  11  22
1  13  24
```

>When doing an operation between DataFrame and Series, the default behavior is to align the Series index on the DataFrame columns, thus broadcasting row-wise. [^6]:

[^6]: https://pandas.pydata.org/docs/user_guide/dsintro.html#indexing-selection

`add()`メソッドの`axis`引数を指定すれば、SeriesのindexをDataFrameのindexに対応させることもできます。

```
In [51]: df.add(s, axis="index")
Out[51]:
    0   1
0  11  12
1  23  24
```


-----
# 比較演算に関するクイズ

------
### 問31: `==`によるSeriesの比較

```
In [100]: s = pd.Series(["foo", "bar"])

In [101]: s
Out[101]:
0    foo
1    bar
dtype: object

# スカラー値との比較
In [1]: s == "foo"

# listとの比較
In [2]: s == ["foo", "bar"]

# numpy arrayとの比較
In [3]: s == np.array(["foo", "bar"])

# 長さの異なるpd.Seriesとの比較
In [4]: s == pd.Series(["foo"])
```

Errorが発生するInputはすべて選択してください。

-----
### 答: 4のみ

```
In [1]: s == "foo"
Out[1]:
0     True
1    False
dtype: bool

In [2]: s == ["foo", "bar"]
Out[2]:
0    True
1    True
dtype: bool

In [3]: s == np.array(["foo", "bar"])
Out[3]:
0    True
1    True
dtype: bool

In [4]: s == pd.Series(["foo"])
---------------------------------------------------------------------------
...
ValueError: Can only compare identically-labeled Series objects
```

スカラー値やarray-likeなオブジェクトと比較できます。ただし、比較する際は長さを一致させる必要があります。[^11]
[^11]: https://pandas.pydata.org/docs/user_guide/basics.html#comparing-array-like-objects


-----
### 問32: `==`によるSeriesの比較 Part2

```
In [203]: s = pd.Series([1.0, np.nan])

In [204]: s
Out[204]:
0    1.0
1    NaN
dtype: float64

In [?]: s == s

Out[1]: True

Out[2]: False

Out[3]: 
0     True
1     True
dtype: bool

Out[4]:
0     True
1    False
dtype: bool
```

適切なOutputを一つ選択してください。

-----
### 答: 4

要素同士を比較した結果（bool）のSeriesが返ります。ただし`np.nan == np.nan`はFalseが返ることに注意してください。

```
In [207]: s == s
Out[207]:
0     True
1    False
dtype: bool

In [208]: np.nan == np.nan
Out[208]: False
```

同じ要素を持っているかどうかは`equals()`で確認できます。[^12]

```
In [210]: s.equals(s)
Out[210]: True
```


[^12]: https://pandas.pydata.org/docs/user_guide/basics.html#comparing-if-objects-are-equivalent


-----
### 問33: Seriesに対するin演算子の結果

```
In [222]: s = pd.Series([0,1], index=["a","b"])

In [223]: s
Out[223]:
a    0
b    1
dtype: int64

# index "a"が含まれているかを確認できる？
In [1]: "a" in s

# value "0"が含まれているかを確認できる？
In [2]: 0 in s

Out[?]: True
```

適切なInputを一つ選んでください。

-----
### 答: 1

>Using the Python in operator on a Series tests for membership in the index, not membership among the values. 
>If this behavior is surprising, keep in mind that using in on a Python dictionary tests keys, not values, and Series are dict-like.  [^21]

[^21]: https://pandas.pydata.org/docs/user_guide/gotchas.html#missing-value-representation-for-numpy-types


```
In [227]: "a" in s
Out[227]: True

In [242]: 0 in s
Out[242]: False

# dictでも確認する
In [228]: d = {"a":1,"b":2}

In [229]: "a" in d
Out[229]: True
```

値が含まれているかは`Series.isin()`で確認できます。

```
In [233]: s.isin([0])
Out[233]:
a     True
b    False
dtype: bool
```



-----
### 問34: DataFrameに対するin演算子の結果


```
In [237]: df = pd.DataFrame({"a":[1,2], "b":[3,4]}, index=["x","y"])

In [238]: df
Out[238]:
   a  b
x  1  3
y  2  4

# index "x"が含まれているかを確認できる？
In [1]: "x" in df

# column "a"が含まれているかを確認できる？
In [2]: "a" in df

# value "1"が含まれているかを確認できる？
In [3]: 1 in df

Out[*]: True
```

適切なInputを一つ選んでください。

-----
### 答: 2


```
In [239]: "x" in df
Out[239]: False

In [240]: "a" in df
Out[240]: True

In [241]: 1 in df
Out[241]: False
```


-----
# その他のクイズ

-----
### 問41: 欠損値を含むデータのsum

```
In [1]: np.sum([1, 2, np.nan])

In [2]: pd.Series([1, 2, np.nan]).sum()
 
In [3]: np.sum(pd.Series([1, 2, np.nan]))

Out[*]: 3.0
```

適切なInputをすべて選んでください。


-----
### 答: 2,3

`Series.sum()`などpandasのdescriptive statisticsなメソッドは、デフォルトでは欠損値を無視します。


```
In [1]: np.sum([1, 2, np.nan])
Out[1]: nan

In [2]: pd.Series([1, 2, np.nan]).sum()
Out[2]: 3.0
 
In [3]: np.sum(pd.Series([1,2,np.nan]))
Out[3]: 3.0
```

`skipna=False`を指定すれば、欠損値は無視されず、結果は`np.nan`になります。

```
In [553]: pd.Series([1, 2, np.nan]).sum(skipna=False)
Out[553]: nan
```

※ `np.sum(pd.Series([1,2,np.nan]))`の結果が`np.nan`でなく`3.0`である原因は分かりませんでした。

>Note that by chance some NumPy methods, like mean, std, and sum, will exclude NAs on Series input by default [^44]

[^44]: https://pandas.pydata.org/docs/user_guide/basics.html#descriptive-statistics


-----

### 問42: 分散を求める


```
# numpyで分散を求める
In [?]: np.array([0]).var()

Out[1]: 0.0

Out[2]: nan

# pandasで分散を求める
In [?]: pd.Series([0]).var()

Out[3]: 0.0

Out[4]: nan
```

適切なOutputを複数選択してください。

-----
### 答: 1, 4

numpyの`var()`では`ddof`（自由度）引数のデフォルト値は0なのに対して、pandasの`var()`ではデフォルト値は1です。

```
In [570]: np.array([0]).var()
Out[570]: 0.0

In [572]: pd.Series([0]).var()
Out[572]: nan

In [574]: pd.Series([0]).var(ddof=0)
Out[574]: 0.0
```


https://stackoverflow.com/questions/75622855/


-----

### 問43: `agg()`に`np.var`を渡す

`agg()`には集約したい関数や関数名を渡すことができます。

```
In [6]: pd.Series([1,2]).agg(["sum"])
Out[6]:
sum    3
dtype: int64
```

```
In [?]: pd.Series([0]).agg([np.var])

Out[1]:
var   0.0
dtype: float64

Out[2]:
var   NaN
dtype: float64
```

適切なOutputを選択してください。

-----
### 答: 2

`np.var`を実行しているように見えますが、実はpandasの`var()`が呼ばれています。ただし、この挙動は将来のバージョンで変わります。

```
In [3]: pd.Series([0]).agg([np.var])
<ipython-input-3-bcf21703d287>:1: FutureWarning: The provided callable <function var at 0x7f71fa7d4c20> is currently using Series.var. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "var" instead.
  pd.Series([0]).agg([np.var])
```

-----

# まとめ


----
### 教訓
* Seriesはlist-likeでもありdict-likeであることを意識する
* Seriesを扱うときはindexを意識する
* SeriesまたDataFrameに対して`[]`でアクセスすると、直観的でない挙動に遭遇するかもしれない。できるだけ`.loc[]`や`.iloc[]`を使った方がよい