Pandas のSeriesとDataFrame

Pandas(データ構造)

Pandasのデータ構造はどうなっているのか? * Series(ラベル付きデータ) * DataFrame(ラベル付きデータが複数)

です。

Series (シリーズ)

直列、連続など、繋がりのある何かの事ですね。Pandasは、スプレッドシート(表計算)と思っていたが思想が違うみたいだ。Seriesが基本でそれの拡張がDataFrameであるのかな。

インデックス(index)、索引、目次だったり、見出しだったりいろいろ意味があるがここではシリーズとして代入する値のラベル(label)
データ(data)、整数、文字列、浮動小数点数Pythonオブジェクトなど値のこと シリーズ(Series)、1次元のラベル付き配列で軸ラベルはまとめてインデックスという。

s = pd.Series(data, index=index)
例として、インデックスのラベルとして駅名、値として東京からの営業キロ。もちろん関係性(紐づいている)があります。を使ってシリーズを作ります

index=["東京","品川","新横浜","名古屋","京都","新大阪","新神戸","姫路","岡山","福山","広島","徳山","新山口","小倉","博多"]
data=[0.0,6.8,28.8,366.0,513.6,552.6,589.5,644.3,732.9,791.2,894.2,982.7,1027,1107.7,1174.9]
s = pd.Series(data,index=index)
s
東京        0.0
品川        6.8
新横浜      28.8
名古屋     366.0
京都      513.6
新大阪     552.6
新神戸     589.5
姫路      644.3
岡山      732.9
福山      791.2
広島      894.2
徳山      982.7
新山口    1027.0
小倉     1107.7
博多     1174.9
dtype: float64
s.index
Index(['東京', '品川', '新横浜', '名古屋', '京都', '新大阪', '新神戸', '姫路', '岡山', '福山', '広島',
       '徳山', '新山口', '小倉', '博多'],
      dtype='object')
pd.Series(data)
0        0.0
1        6.8
2       28.8
3      366.0
4      513.6
5      552.6
6      589.5
7      644.3
8      732.9
9      791.2
10     894.2
11     982.7
12    1027.0
13    1107.7
14    1174.9
dtype: float64

indexがあるほうが分かりやすいですね。インデックスは、Str文字列なのでオブジェクト型になるみたいです。indexがなくても数値の羅列だけでもシリーズは作れます。測定(measure)データや記録(record)データなどを代入できるということですね。

Seriesのdata

をdataとして扱える Seriesにはindexが必要、Seriesを作るときindexを指定しないと0から始まる数値の番号が付く。 ゆえに、辞書の場合、keyとvalueがindex,dataの関係で1対1。1次元配列の場合は、指定するindexと配列数が同じサイズ出ないとErrorになる。スカラー値の場合同じ値の連続という(ブロードキャスト)意味もあるのでindexが指定されていればそれだけの分のデータをスカラー値の同じ値で埋めるのでErrorにはならない。

配列をもとに作る

import numpy as np
s = pd.Series(np.arange(0,3*10,3))
s
0     0
1     3
2     6
3     9
4    12
5    15
6    18
7    21
8    24
9    27
dtype: int32



s = pd.Series(np.arange(0,3*10,3),index=['A','B','C'])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-15-763913bcc66a> in <module>
----> 1 s = pd.Series(np.arange(0,3*10,3),index=['A','B','C'])

h:\Anaconda3\lib\site-packages\pandas\core\series.py in __init__(self, data, index, dtype, name, copy, fastpath)
    247                             'Length of passed values is {val}, '
    248                             'index implies {ind}'
--> 249                             .format(val=len(data), ind=len(index)))
    250                 except TypeError:
    251                     pass

ValueError: Length of passed values is 10, index implies 3

indexとdata数がミスマッチすると「ValueError」になる

s = pd.Series(np.arange(0,3*10,3),index=['A','B','C','D','E','F','G','H','I','J'])
s
A     0
B     3
C     6
D     9
E    12
F    15
G    18
H    21
I    24
J    27
dtype: int32
s = pd.Series([0,3,6,9,12,15,18,21,24,27],index=['A','B','C','D','E','F','G','H','I','J'])
s = pd.Series([0,3,6,9,12,15,18,21,24,27])
s = pd.Series([0,3,6,9,12,15,18,21,24,27],index=['A','A','A','A','A','A','A','A','A','A'])
s
A     0
A     3
A     6
A     9
A    12
A    15
A    18
A    21
A    24
A    27
dtype: int64

index値が一意(ほかの値とダブル、被る)でなくてもErrorにはならないがサポートされてないメソッドもある。

辞書をもとに作る

x3 = {}
x3['3x1'] = 3
x3['3x2'] = 6
x3['3x3'] = 9
x3['3x4'] = 12
x3['3x5'] = 15
pd.Series(x3)
3x1     3
3x2     6
3x3     9
3x4    12
3x5    15
dtype: int64
pd.Series({"壱":1,"弐":2,"参":3})
壱    1
弐    2
参    3
dtype: int64

データが辞書形式の場合、PythonとPandasのVersionによって、Seriesに登録される順番が変わる。知っての通り辞書型はindex(呼び出しオブジェクト)が自由で処理のスピードの観点からindex形式が数値だけだとしてもソートした順番で内部処理しているわけではない。'list(dict)','sorted(dict)'のどちらをとるかの違い。前者が代入順、後者がkeyをソートした順になっている。バージョンによってSeriesに代入される順が変わるので注意が必要。

辞書形式を使うときにもindex指定ができる。index指定をすると辞書型変数から必要なものだけをSeries化できる

di = {"壱":1,"弐":2,"参":3,'一':1,'二':2,'三':3,'四':4,'五':5,'六':6,'七':7,'八':8,'九':9}
pd.Series(di,["壱","弐","参","九","十","壱","壱"])
壱    1.0
弐    2.0
参    3.0
九    9.0
十    NaN
壱    1.0
壱    1.0
dtype: float64

diの辞書型からindexに登録したいものだけをリスト化してindexに入れることができる。ただし辞書に登録されてないものをdata化しようとするとErrorではなくNaN(数値ではない)として登録される。本来の意味ではなく該当値がないという意味である。

di2 = dict([(di[x],x) for x in list(di)])
di2
{1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六', 7: '七', 8: '八', 9: '九'}
pd.Series(di2,[7,8,9,10])
7       七
8       八
9       九
10    NaN
dtype: object

たしかにオブジェクトは、'Not a Number'非数であるけどさ

スカラー値をもとに作る

スカラー値をもとに作るとindexの長さに一致するように値を入力する。

pd.Series(1)
0    1
dtype: int64
pd.Series(1,index=list("ABCDEF"))
A    1
B    1
C    1
D    1
E    1
F    1
dtype: int64

空のシリーズ

pd.Series()
Series([], dtype: float64)

Numpyな動作

NumpyのndarrayとSeriesは、似た動作をする。

s = pd.Series([0,3,6,9,12,15,18,21,24,27],index=['A','B','C','D','E','F','G','H','I','J'])
s[0]
0
s[:5]
A     0
B     3
C     6
D     9
E    12
dtype: int64
s[s> s.median()]
F    15
G    18
H    21
I    24
J    27
dtype: int64
s[[4,3,1]]
E    12
D     9
B     3
dtype: int64
np.pi*s**2
A       0.000000
B      28.274334
C     113.097336
D     254.469005
E     452.389342
F     706.858347
G    1017.876020
H    1385.442360
I    1809.557368
J    2290.221044
dtype: float64

Numpyのように pandas Series は、dtype(データタイプ)を持っている

s.dtype
dtype('int64')

このdtypeは、Numpyと同じだが一部拡張されておりExtensionDtypeとなっている。

s.array
<PandasArray>
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
Length: 10, dtype: int64
type(s)
pandas.core.series.Series
type(s.array)
pandas.core.arrays.numpy_.PandasArray

Seriesを配列として扱いたい場合はSeries.arrayを使う。使えるNumpy メソッド等が増える。この配列も一部拡張されたExtensionArrayとなっている。Seriesはndarrayに似ているが、実際のndarrayが必要な場合はSeries.to_numpy()を使用する。

s_array = s.to_numpy()
s_array
array([ 0,  3,  6,  9, 12, 15, 18, 21, 24, 27], dtype=int64)
type(s_array)
numpy.ndarray

辞書形式な動作

Seriesは、インデックス(ラベル)で値を取得および設定できるので固定サイズの辞書ともいえる。

Python 辞書形式と同じようにdataの追加、変更、削除、indexの有り無し確認などができる

s = pd.Series([0,3,6,9,12,15,18,21,24,27],index=['A','B','C','D','E','F','G','H','I','J'])
s['A']
0
s['I']
24
s
A     0
B     3
C     6
D     9
E    12
F    15
G    18
H    21
I    24
J    27
dtype: int64
s['A'] = -1
s['A']
-1
s['K'] = 33
'D' in s
True
del s['J']
'J' in s
False



s['J']
KeyError: 'J'
s
A    -1
B     3
C     6
D     9
E    12
F    15
G    18
H    21
I    24
K    33
dtype: int64

getメソッドを使うとラベルが見つからない処理が便利。getメソッドは、indexlabelがないときNoneまたは指定されたデフォルトが返される。

s.get('J')
type(s.get('J'))
NoneType
s.get('J', np.nan)
nan
s.get('J', 0)
0
s.get('J', 'データがありません')
'データがありません'

Seriesとndarrayの主な違いは、Series間の操作ではラベルに基づいてデータが自動的に整列されることです。したがって、関係するシリーズが同じラベルを持つかどうかを考慮せずに計算を書くことができます。

s[1:] + s[:-1]
A     NaN
B     6.0
C    12.0
D    18.0
E    24.0
F    30.0
G    36.0
H    42.0
I    48.0
K     NaN
dtype: float64

位置合わせされていないシリーズ間の演算の結果は、関連するインデックスの和集合になります。あるシリーズまたは別のシリーズでラベルが見つからない場合、結果は欠落としてマークされNaNます。明示的なデータアライメントを行わずにコードを記述できるようになると、対話型のデータ分析と研究に非常に大きな自由と柔軟性が与えられます。パンダデータ構造の統合されたデータ整列機能は、ラベル付きデータを扱うための関連ツールの大部分とは別にパンダを設定します。

同じインデックスがない演算は、演算できないためNaN(欠陥データ)になる。dropna関数を使って、データが欠けているラベルを削除することもできる。

s1 =  s[1:] + s[:-1]
s1.dropna()
B     6.0
C    12.0
D    18.0
E    24.0
F    30.0
G    36.0
H    42.0
I    48.0
dtype: float64

名前属性

indexのほかにもSeriesに名前を付けることができる。変数名のほかにオブジェクト内部で名前が保持される。

s = pd.Series(np.random.randn(5), name='something')
s
0   -0.284847
1   -0.368176
2    0.295479
3    0.432335
4   -0.894993
Name: something, dtype: float64

Series nameは、多くの場合自動的に割り当てられます。特に、以下に示すように、DataFrameから1Dスライスしたときなど

s1 = s.rename("different")
s1.name
'different'
s1
0   -0.284847
1   -0.368176
2    0.295479
3    0.432335
4   -0.894993
Name: different, dtype: float64
s
0   -0.284847
1   -0.368176
2    0.295479
3    0.432335
4   -0.894993
Name: something, dtype: float64
s1.name = 'original'
s1
0   -0.284847
1   -0.368176
2    0.295479
3    0.432335
4   -0.894993
Name: original, dtype: float64

DataFrame(データフレーム)

DataFrameは、潜在的に異なる型の列を持つ2次元のラベル付きデータ構造。スプレッドシートSQLテーブル、あるいはSeriesオブジェクトの辞書のように考えることができる。Pandasでは、DataFrameが良く使われる。Seriesと同様に、DataFrameはさまざまな種類の入力を受け入れる。

  • 1次元のndarrays、リスト、辞書、またはシリーズのDict
  • 2D numpy.ndarray
  • 構造化またはレコード ndarray
  • A Series
  • もう一つ DataFrame

データとともに、オプションでindex(行ラベル)および columns(列ラベル)引数を渡すことができる。インデックスやカラムスを渡すと、結果として得られるDataFrameのインデックスやカラムスを保証することになります。したがって、Seriesと特定のインデックスの辞書は、渡されたインデックスに一致しないすべてのデータを破棄する。

軸ラベルが渡されない場合、それらは常識的な規則に基づいて入力データから構築される。

辞書からDataFrameを作る

結果のインデックスは、さまざまなシリーズのインデックスの和集合になります。入れ子になった辞書があれば、それらは最初にSeriesに変換されます。列が渡されない場合、列は辞書キーの順序付きリストになります。

d = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
     'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
df
one two
a 1.0 1.0
b 2.0 2.0
c 3.0 3.0
d NaN 4.0
 pd.DataFrame(d, index=['d', 'b', 'a'])
one two
d NaN 4.0
b 2.0 2.0
a 1.0 1.0
pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three'])
two three
d 4.0 NaN
b 2.0 NaN
a 1.0 NaN

行ラベルと列ラベルはそれぞれindex属性とcolumns属性にアクセスすることでアクセスでき ます。

注意 特定の列のセットがデータの辞書と共に渡されると、渡された列は辞書のキーをオーバーライドします。

df.index
Index(['a', 'b', 'c', 'd'], dtype='object')
df.columns
Index(['one', 'two'], dtype='object')

ndarraysはすべて同じ長さでなければなりません。インデックスが渡される場合、インデックスも明らかに配列と同じ長さでなければなりません。インデックスが渡されなかった場合、結果は次のようrange(n)になります。ここnで、は配列の長さです。

d = {'one': [1., 2., 3., 4.],
     'two': [4., 3., 2., 1.]}
pd.DataFrame(d)
one two
0 1.0 4.0
1 2.0 3.0
2 3.0 2.0
3 4.0 1.0
pd.DataFrame(d, index=['a', 'b', 'c', 'd'])
one two
a 1.0 4.0
b 2.0 3.0
c 3.0 2.0
d 4.0 1.0

構造化配列またはレコード配列から

この場合は、一連の配列と同じように処理されます。

data = np.zeros((2, ), dtype=[('A', 'i4'), ('B', 'f4'), ('C', 'a10')])
data[:] = [(1, 2., 'Hello'), (2, 3., "World")]
data
array([(1, 2., b'Hello'), (2, 3., b'World')],
      dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')])
df = pd.DataFrame(data)
df
A B C
0 1 2.0 b'Hello'
1 2 3.0 b'World'
df.index
RangeIndex(start=0, stop=2, step=1)
df.index.dtype
dtype('int64')
df.columns
Index(['A', 'B', 'C'], dtype='object')
df.columns.dtype
dtype('O')
pd.DataFrame(data, columns=['C', 'A', 'B'])
C A B
0 b'Hello' 1 2.0
1 b'World' 2 3.0
pd.DataFrame(data, index=['first', 'second'])
A B C
first 1 2.0 b'Hello'
second 2 3.0 b'World'

注意 DataFrameは、2次元のNumPy ndarrayのように機能することを目的としていません。 DataFrameは、純粋なNumPy ndarrayをラベル付きで扱うのではなく、各カラムにいろいろなSeriesが入っていると考えたほうが良い

辞書のリストから

data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
pd.DataFrame(data2)
a b c
0 1 2 NaN
1 5 10 20.0
pd.DataFrame(data2, index=['first', 'second'])
a b c
first 1 2 NaN
second 5 10 20.0
pd.DataFrame(data2, columns=['a', 'b'])
a b
0 1 2
1 5 10

タプルの辞書から作る

タプル辞書を渡すことで、MultiIndexedフレームを自動的に作成できます。

tuple_dict = {('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
                ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
                ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
                ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
                ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}}
tuple_dict
{('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
 ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
 ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
 ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
 ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}}
tuple_dict[('a', 'b')]
{('A', 'B'): 1, ('A', 'C'): 2}
pd.DataFrame(tuple_dict)
a b
b a c a b
A B 1.0 4.0 5.0 8.0 10.0
C 2.0 3.0 6.0 7.0 NaN
D NaN NaN NaN NaN 9.0

なんだこれは?

tuple_dict2={}
shinyoko={}
shinyoko[('(着)東京','運賃')]=500
shinyoko[('(着)東京','指定席')]=2460
shinyoko[('(着)東京','自由席')]=860
shinyoko[('(着)品川','運賃')]=170
shinyoko[('(着)品川','指定席')]=2460
shinyoko[('(着)品川','自由席')]=860
shinyoko2={}
shinyoko2[('(着)東京','運賃')]=500*2
shinyoko2[('(着)東京','指定席')]=2460*2
shinyoko2[('(着)東京','自由席')]=860*2
shinyoko2[('(着)品川','運賃')]=170*2
shinyoko2[('(着)品川','指定席')]=2460*2
shinyoko2[('(着)品川','自由席')]=860*2
shinagawa={}
shinagawa[('(着)東京','運賃')]=170
shinagawa[('(着)東京','指定席')]=2460
shinagawa[('(着)東京','自由席')]=860
shinagawa[('(着)新横浜','運賃')]= 410
shinagawa[('(着)新横浜','指定席')]=2460
shinagawa[('(着)新横浜','自由席')]=860
shinagawa2={}
shinagawa2[('(着)東京','運賃')]=170*2
shinagawa2[('(着)東京','指定席')]=2460*2
shinagawa2[('(着)東京','自由席')]=860*2
shinagawa2[('(着)新横浜','運賃')]= 410*2
shinagawa2[('(着)新横浜','指定席')]=2460*2
shinagawa2[('(着)新横浜','自由席')]=860*2
tokyo={}
tokyo[('(着)品川','運賃')]= 170
tokyo[('(着)品川','指定席')]= 2460
tokyo[('(着)品川','自由席')]= 860
tokyo[('(着)新横浜','運賃')]= 500
tokyo[('(着)新横浜','指定席')]= 2460
tokyo[('(着)新横浜','自由席')]= 860
tokyo2={}
tokyo2[('(着)品川','運賃')]= 170*2
tokyo2[('(着)品川','指定席')]= 2460*2
tokyo2[('(着)品川','自由席')]= 860*2
tokyo2[('(着)新横浜','運賃')]= 500*2
tokyo2[('(着)新横浜','指定席')]= 2460*2
tokyo2[('(着)新横浜','自由席')]= 860*2

tuple_dict2[('(発)東京','片道')] = tokyo
tuple_dict2[('(発)東京','往復')] = tokyo2
tuple_dict2[('(発)品川','片道')] = shinagawa
tuple_dict2[('(発)品川','往復')] = shinagawa2
tuple_dict2[('(発)新横浜','片道')] = shinyoko
tuple_dict2[('(発)新横浜','往復')] = shinyoko2

pd.DataFrame(tuple_dict2)
(発)東京 (発)品川 (発)新横浜
片道 往復 片道 往復 片道 往復
(着)品川 指定席 2460.0 4920.0 NaN NaN 2460.0 4920.0
自由席 860.0 1720.0 NaN NaN 860.0 1720.0
運賃 170.0 340.0 NaN NaN 170.0 340.0
(着)新横浜 指定席 2460.0 4920.0 2460.0 4920.0 NaN NaN
自由席 860.0 1720.0 860.0 1720.0 NaN NaN
運賃 500.0 1000.0 410.0 820.0 NaN NaN
(着)東京 指定席 NaN NaN 2460.0 4920.0 2460.0 4920.0
自由席 NaN NaN 860.0 1720.0 860.0 1720.0
運賃 NaN NaN 170.0 340.0 500.0 1000.0

こういう、ことか?MultiIndexedとは、indexやcolumnsをグループ化した状態みたいな

Seriesから作る

結果は、入力Seriesと同じインデックスを持ち、その名前がSeriesの元の名前である1つの列を持つDataFrameになります(他の列名が指定されていない場合のみ)。 欠損データを含むDataFrameを構築するには、欠損値を表すためにnp.nanを使用します。 あるいは、numpy.MaskedArrayをDataFrameコンストラクターへのデータ引数として渡すと、マスクされたエントリは存在しないと見なされます。

s = pd.Series([0,3,6,9,12,15],index=['A','B','C','D','E','F'],name ='example')
s['D']=np.nan
s
A     0.0
B     3.0
C     6.0
D     NaN
E    12.0
F    15.0
Name: example, dtype: float64
pd.DataFrame(s)
example
A 0.0
B 3.0
C 6.0
D NaN
E 12.0
F 15.0
s = pd.Series([0,3,6,9,12,15],index=['A','B','C','D','E','F'],name ='example')
mask_s =[False] * len(s)
mask_s[3] = True
mask_s
[False, False, False, True, False, False]
masked_s=np.ma.masked_array(s , mask=mask_s)
masked_s
masked_array(data=[0, 3, 6, --, 12, 15],
             mask=[False, False, False,  True, False, False],
       fill_value=999999,
            dtype=int64)
type(masked_s)
numpy.ma.core.MaskedArray
pd.DataFrame(masked_s)
0
0 0.0
1 3.0
2 6.0
3 NaN
4 12.0
5 15.0

代替コンストラクタで作る

DataFrame.from_dict 辞書の辞書または配列のような文字列の辞書を取り、DataFrameを返します。これは、デフォルトではあるがdictキーを行ラベルとして使用するために設定できるパラメータをDataFrame除いて、コンストラクタのように動作します。 オプションorientについて'columns''index'

dic = dict([('A', [1, 2, 3]), ('B', [4, 5, 6])])
dic
{'A': [1, 2, 3], 'B': [4, 5, 6]}
pd.DataFrame.from_dict(dic)
A B
0 1 4
1 2 5
2 3 6
pd.DataFrame.from_dict(dic,orient='columns')
A B
0 1 4
1 2 5
2 3 6
pd.DataFrame.from_dict(dic,orient='index')
0 1 2
A 1 2 3
B 4 5 6
pd.DataFrame.from_dict(dic,orient='index',columns=['one', 'two', 'three'])
one two three
A 1 2 3
B 4 5 6

辞書をもとにしたときに、keyとvalueがindex,column列になるがorientを使って逆にすることも可能

DataFrame.from_records

DataFrame.from_recordsタプルのリストまたは構造化dtypeを持つndarrayを取ります。DataFrame結果のDataFrameインデックスが構造化dtypeの特定のフィールドになる場合があることを除けば、通常のコンストラクタと同様に機能します。

data = np.zeros((2, ), dtype=[('A', 'i4'), ('B', 'f4'), ('C', 'U10')])
data[:] = [(1, 2., 'Hello'), (2, 3., "World")]
data
array([(1, 2., 'Hello'), (2, 3., 'World')],
      dtype=[('A', '<i4'), ('B', '<f4'), ('C', '<U10')])
df = pd.DataFrame.from_records(data, index='C')
df
A B
C
Hello 1 2.0
World 2 3.0
df.index
Index(['Hello', 'World'], dtype='object', name='C')
df.index.dtype
dtype('O')

列選択、追加、削除

DataFrameを意味的に同じインデックスのSeriesオブジェクトの辞書のように扱うことができます。列の取得、設定、削除は、類似の辞書操作と同じ構文で動作します。

df = pd.DataFrame([[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]],
                  columns=['A', 'B', 'C'],index=['one','two','three','four'])
df
A B C
one 1 2 3
two 4 5 6
three 7 8 9
four 10 11 12
df['A']
one       1
two       4
three     7
four     10
Name: A, dtype: int64
df['C'] = df['A'] * df['B']
df
A B C
one 1 2 2
two 4 5 20
three 7 8 56
four 10 11 110
df['flag'] = df['A'] > 2
df
A B C flag
one 1 2 2 False
two 4 5 20 True
three 7 8 56 True
four 10 11 110 True

列は辞書を使って削除またはポップすることができます。

del df['B']
c = df.pop('C')
c
one        2
two       20
three     56
four     110
Name: C, dtype: int64
type(c)
pandas.core.series.Series
df
A flag
one 1 False
two 4 True
three 7 True
four 10 True

スカラー値を挿入すると、当然、列を埋めるために伝搬されます。

df['foo'] = 'bar'
df
A flag foo
one 1 False bar
two 4 True bar
three 7 True bar
four 10 True bar

DataFrameと同じインデックスを持たないSeriesを挿入すると、DataFrameのインデックスに準拠します。

df['A_trunc'] = df['A'][:2]
df
A flag foo A_trunc
one 1 False bar 1.0
two 4 True bar 4.0
three 7 True bar NaN
four 10 True bar NaN

生のndarrayを挿入できますが、それらの長さはDataFrameのインデックスの長さと一致しなければなりません。 デフォルトでは、列は最後に挿入されます。このinsert関数は列の特定の位置に挿入するのに利用できます。

A列の内容をA列の後ろに'bar'列として挿入

df.insert(1, 'bar', df['A'])
df
A bar flag foo A_trunc
one 1 1 False bar 1.0
two 4 4 True bar 4.0
three 7 7 True bar NaN
four 10 10 True bar NaN
del df['bar']
df
A flag foo A_trunc
one 1 False bar 1.0
two 4 True bar 4.0
three 7 True bar NaN
four 10 True bar NaN
df.columns
Index(['A', 'flag', 'foo', 'A_trunc'], dtype='object')
list(df.columns).index('A')
0
list(df.columns).index('flag')
1
list(df.columns).index('foo')
2
df.insert(list(df.columns).index('foo'), '前','左')
df.insert(list(df.columns).index('foo')+1, '後','右')
df
A flag foo A_trunc
one 1 False bar 1.0
two 4 True bar 4.0
three 7 True bar NaN
four 10 True bar NaN