Python スライス(抽出

スポンサーリンク

Pythonでは文字列や配列から任意の文字や行を抽出することが簡単にできます。これをスライスと言います。

スポンサーリンク

文字列をスライス

最初の文字、最後の文字

data = "abcdef"

# 最初の文字
print(data[0])
# a

# 最後の文字
print(data[-1])
# f

最初のN文字目まで、最後のN文字目まで

最初のN文字はdf[:終了位置]、最後のN文字はdf[開始位置:]となります。開始位置は最後から数えた場合はマイナスにします。終了位置は未満となります。

data = "abcdef"

# 最初の2文字
print(data[:2])
# ab

# 最後の2文字
print(data[-2:])
# ef

任意の複数文字

df[開始位置:終了位置]と位置を指定します。開始位置は以上、終了位置は未満となります。未満となるところを注意しましょう。

data = "abcdef"

# 1文字目以上、3文字目の文字
print(data[1:3])
# bc

# 最後から4文字目以上、最後から2文字目の文字
print(data[-4:-2])
# cd

以下のように、「初めから」と「最後から」を混ぜて使うこともできます。

# 1文字目以上、最後から3文字目未満の行
print(data[1:-3])

配列(リスト型、タプル型)をスライス

ここではリスト型で説明しますが、タプル型も同じです。

最初の要素、最後の要素

data = [1, 2, 3, 4, 5]

# 最初の要素
print(data[0])
# 1

# 最後の要素
print(data[-1])
# 5

最初のN個目まで、最後のN個目まで

最初のN個はdf[:終了位置]、最後のN個はdf[開始位置:]となります。開始位置は最後から数えた場合はマイナスにします。終了位置は未満となります。

data = [1, 2, 3, 4, 5]

# 最初の2個
print(data[:2])
# [1, 2]

# 最後の2個
print(data[-2:])
# [4, 5]

任意の複数の要素

df[開始位置:終了位置]と位置を指定します。開始位置は以上、終了位置は未満となります。未満となるところを注意しましょう。

data = [1, 2, 3, 4, 5]

# 1個目以上、3個目未満の文字
print(data[1:3])
# [2, 3]

# 最後から4個目以上、最後から2個目未満の文字
print(data[-4:-2])
# [2, 3]

以下のように、「初めから」と「最後から」を混ぜて使うこともできます。

# 1個目以上、最後から2個目未満の行 
print(data[1:-2])

二次配列(Numpy、Pandas)を行でスライス

最初の行、最後の行

df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], columns = ["aaa", "bbb", "ccc"]) 

print(df)
#    aaa  bbb  ccc
# 0    1    2    3
# 1    4    5    6
# 2    7    8    9
# 3   10   11   12

# 最初の行
print(df[:1])
#    aaa  bbb  ccc
# 0    1    2    3

# 最後の行
print(df[-1:])
#    aaa  bbb  ccc
# 3   10   11   12

Pandasでは以下のように取得することもできます。

# 最初の行
print(df.head(1))

# 最後の行
print(df.tail(1))

Numpyは配列と同じ考えなので、以下のように取得することもできます。

# 最初の行
print(data[0])

# 最後の行
print(data[-1])

最初のN行目まで、最後のN行目まで

最初のN行はdf[:終了行]、最後のN行はdf[開始行:]となります。開始行は最後から数えた場合はマイナスにします。

df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], columns = ["aaa", "bbb", "ccc"])

print(df)
#    aaa  bbb  ccc
# 0    1    2    3
# 1    4    5    6
# 2    7    8    9
# 3   10   11   12

# 最初の2行
print(df[:2])
#    aaa  bbb  ccc
# 0    1    2    3
# 1    4    5    6

# 最後の2行
print(df[-2:])
#    aaa  bbb  ccc
# 2    7    8    9
# 3   10   11   12

Pandasでは以下のように取得することもできます。
df.head(行数)df.tail(行数)
Nを指定しない場合は、デフォルト5行となります。

# 最初の行
print(df.head(2))

# 最後の行
print(df.tail(2))

任意の複数行

df[開始行:終了行]と行数を指定します。開始行は以上、終了行は未満となります。未満となるところを注意しましょう。

df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], columns = ["aaa", "bbb", "ccc"])

print(df)
#    aaa  bbb  ccc
# 0    1    2    3
# 1    4    5    6
# 2    7    8    9
# 3   10   11   12

# 1行目以上、2行目未満の行
print(df[1:2])
#    aaa  bbb  ccc
# 1    4    5    6

# 最後から3行目以上、最後から2行目未満の行
print(df[-3:-2])
#    aaa  bbb  ccc
# 1    4    5    6

以下のように、初めからと最後からを混ぜて使うこともできます。

# 1行目以上、最後から2行目未満の行
print(df[1:-2])

二次配列(Numpy、Pandas)を日時でスライス

前提として、インデックスは日時型(datetime)にする必要があります。

基本的には、行数と同じです。

df["開始日時":"終了日時"]、またはdf["開始日":"終了日"]

しかし、行でスライスする場合は「終了行は未満」でしたが、日付では「時間を無視して日付の以下」となります。
以下の1つ目の例では、”2020/05/02″以下の行を抽出していますが、2020/05/02 16:34:56 がヒットしています。ところが、”2020/05/02 16:00″で抽出すると、2020/05/02 16:34:56 がヒットしません。
2つ目の例の時間を指定した場合は「秒を無視して日時分の以下」となります。
このように少し仕組みが難解ですので、必ず動作確認しましょう
もしくは、”2020/05/01″以下とする場合は、日付のみとせず、”2020/05/01 23:59:59″のように日時秒を指定しましょう

df = pd.DataFrame([["2020/05/01 12:34:56",1,True],["2020/05/02 16:34:56",4,False]], columns = ["Date Time", "aaa", "bbb"]) # リスト型のデータで作成
df.index = pd.DatetimeIndex(pd.to_datetime(df['Date Time']), name='Date Time')
del df['Date Time']

print(df)
#                      aaa    bbb
# Date Time                      
# 2020-05-01 12:34:56    1   True
# 2020-05-02 16:34:56    4  False

print(df[:"2020/05/02"])
#                      aaa    bbb
# Date Time                      
# 2020-05-01 12:34:56    1   True
# 2020-05-02 16:34:56    4  False
        
print(df[:"2020/05/02 16:00"])
#                      aaa   bbb
# Date Time                     
# 2020-05-01 12:34:56    1  True

データ分割(トレーニングとテストデータに分ける

データ分割(トレーニングとテストデータに分けるのページを参照してください。

タイトルとURLをコピーしました