pandasでDataFrameの最初(一番左)に列を追加・挿入する方法。
環境:pandasのversionは0.25.3です。
列名を指定して追加する方法だと末尾(最後、右端)に追加される
既存のDataFrameに1つの列を新規に追加する最も一般的な方法は、df['new_column'] = (追加したい値)
だろう。しかしこの方法では、新しい列は一番右に追加されてしまう。
例を見てみよう。
import pandas as pd
pd.__version__
'0.25.3'
df = pd.DataFrame({ 'name' : ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Fred'], 'English' : [12, 34, 56, 78, 90, 100], 'Math' : [88, 66, 55, 44, 22, 11] }) df
name | English | Math | |
---|---|---|---|
0 | Alice | 12 | 88 |
1 | Bob | 34 | 66 |
2 | Charlie | 56 | 55 |
3 | David | 78 | 44 |
4 | Eve | 90 | 22 |
5 | Fred | 100 | 11 |
df['new_column'] = 'value'
df['new_column_2'] = ['a', 'b', 'c', 'd', 'e', 'f']
df
name | English | Math | new_column | new_column_2 | |
---|---|---|---|---|---|
0 | Alice | 12 | 88 | value | a |
1 | Bob | 34 | 66 | value | b |
2 | Charlie | 56 | 55 | value | c |
3 | David | 78 | 44 | value | d |
4 | Eve | 90 | 22 | value | e |
5 | Fred | 100 | 11 | value | f |
確かに右側に追加されている。
先頭(最初、左端)に追加するにはinsertを使う
pandas.DataFrame.insert()関数
公式ドキュメント:pandas.DataFrame.insert — pandas 1.0.3 documentation
メジャーアップデートされた1.0.0のドキュメントを参照していいのか微妙ですが、多分ここに変更はないでしょう。
insertはドキュメントに記載の通り「指定した好きな位置に列を挿入する」関数である。したがってこれで先頭を指定すれば良い。
loc, column, valueは指定必須。
loc
が「列を挿入する位置」なので、先頭に入れたければ0を指定する。0 <= loc <= len(columns)
でなければならない。
column
は列名。
value
は単一の値ならばその値を全行に指定、SeriesやArrayならばそれぞれの値を指定、だろうな。
valueの型は
int, Series, or array-like
って公式ドキュメントには書いてあるけど、文字列(str)を指定して普通に列を追加できたんだけど……あれ?
上に書いたのと同じ文で再度dfを作った後に df.insert(0, 'new_column', 'value') df
new_column | name | English | Math | |
---|---|---|---|---|
0 | value | Alice | 12 | 88 |
1 | value | Bob | 34 | 66 |
2 | value | Charlie | 56 | 55 |
3 | value | David | 78 | 44 |
4 | value | Eve | 90 | 22 |
5 | value | Fred | 100 | 11 |
df.insert(0, 'new_column_2', ['a', 'b', 'c', 'd', 'e', 'f']) df
new_column_2 | new_column | name | English | Math | |
---|---|---|---|---|---|
0 | a | value | Alice | 12 | 88 |
1 | b | value | Bob | 34 | 66 |
2 | c | value | Charlie | 56 | 55 |
3 | d | value | David | 78 | 44 |
4 | e | value | Eve | 90 | 22 |
5 | f | value | Fred | 100 | 11 |
df.insert(0, 'new_column_error', ['a', 'b', 'c', 'd', 'e']) # 6行ぶんを書くべきところ、要素数5の配列を入れた
エラー(内容はクリックすると展開されます)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-11-bca86ac7c013> in <module> ----> 1 df.insert(0, 'new_column_error', ['a', 'b', 'c', 'd', 'e']) # 6行ぶんを書くべきところ、要素数5の配列を入れた /usr/local/lib/python3.7/site-packages/pandas/core/frame.py in insert(self, loc, column, value, allow_duplicates) 3588 """ 3589 self._ensure_valid_index(value) -> 3590 value = self._sanitize_column(column, value, broadcast=False) 3591 self._data.insert(loc, column, value, allow_duplicates=allow_duplicates) 3592 /usr/local/lib/python3.7/site-packages/pandas/core/frame.py in _sanitize_column(self, key, value, broadcast) 3747 3748 # turn me into an ndarray -> 3749 value = sanitize_index(value, self.index, copy=False) 3750 if not isinstance(value, (np.ndarray, Index)): 3751 if isinstance(value, list) and len(value) > 0: /usr/local/lib/python3.7/site-packages/pandas/core/internals/construction.py in sanitize_index(data, index, copy) 610 611 if len(data) != len(index): --> 612 raise ValueError("Length of values does not match length of index") 613 614 if isinstance(data, ABCIndexClass) and not copy: ValueError: Length of values does not match length of index
なお、すでにある列名を指定するとエラーValueError: cannot insert new_column, already exists
が返ります。
それでは。