Python Pandasのソート(並び順の変更)と抽出(条件)

スポンサーリンク
スポンサーリンク

はじめに

複数のインデックスのことをPandasではマルチインデックス(MultiIndex)と言いますが、このページでは説明していません。
マルチインデックス(MultiIndex)ついては、以下を参照してください。
Pythonのマルチインデックス(MultiIndex)

行のソート(並び順の変更

インデックスにて

df = pd.DataFrame([[1,2,3],[4,None,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成

print(df)
#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9

# 降順
df = df.sort_index(ascending=False)

print(df)

#    aaa  bbb  ccc
# 2    7  8.0    9
# 1    4  NaN    6
# 0    1  2.0    3


# 昇順
df = df.sort_index()

print(df)

#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9
パラメーターはいろいろありますが投資の上では不要かと思います。ドキュメントは以下になります。
pandas.DataFrame.sort_index — pandas 1.2.4 documentation

値にて

df = pd.DataFrame([[1,2,3],[4,None,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"]) # リスト型のデータで作成

print(df)
#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9


# 降順
df = df.sort_values('aaa', ascending=False)

print(df)

#    aaa  bbb  ccc
# 2    7  8.0    9
# 1    4  NaN    6
# 0    1  2.0    3


# 昇順
df = df.sort_values('aaa')

print(df)

#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9
複数列でソートをしたい場合はカラム名をリストで指定します。この場合、リストの終わりからソートされます。
例はドキュメントにありますよ。
pandas.DataFrame.sort_values — pandas 1.2.4 documentation

列のソート(並び順の変更

df.reindex(columns=[カラム名1, カラム名2, ・・・])を用いて、任意の列順に並び替えることが可能です。

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

print(df)
#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9

df = df.reindex(columns=["ccc", "aaa", "bbb"])
print(df)
#    ccc  aaa  bbb
# 0    3    1  2.0
# 1    6    4  NaN
# 2    9    7  8.0

 

抽出(条件)

基本

以下のようにdf[条件式]とすると抽出ができます。

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

print(df)
#                            bbb    ccc
# Date Time                            
# 2020-04-01 12:34:56+00:00    1   True
# 2020-05-01 16:34:56+00:00    4  False
                           bbb    cc

print(df[df.bbb > 1])
#                            bbb    ccc
# Date Time                            
# 2020-05-01 16:34:56+00:00    4  False
条件式のところですが、PythonのIF文と異なるところがありとても重要です。
&|~を使う。
・条件毎にカッコ()で囲む。
・条件式のカラムの指定は、df.bbbではなく、df["bbb"]と指定することもできます。

含む

.isin(リスト型)を使用します。

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

print(df[df["aaa"].isin([1, 4])])
#    aaa  bbb  ccc
# 0    1    2    3
# 1    4    5    6
df.query("aaa in [1, 4]")としても同じように抽出することができます。

文字列の含む(特定文字、前方一致、後方一致)

特定文字を含む

str.contains(検索文字, case=False)で抽出することができます。

df = pd.DataFrame(
    [
        ["2020/05/01 12:34:56",1,True,"xyzA"],
        ["2020/05/01 12:34:56",1,True,"yyzB"],
        ["2020/05/01 16:34:56",1,False,"zzzC"],
        ["2020/05/01 20:34:56",4,False,"xzyA"],
    ], 
    columns = ["DateTime", "aaa", "bbb", "ccc"]
)
df['DateTime'] = pd.to_datetime(df['DateTime'])
print(df)
#              DateTime  aaa    bbb
# 0 2020-05-01 12:34:56    1   True
# 1 2020-05-01 12:34:56    2   True
# 2 2020-05-01 16:34:56    1   True
# 3 2020-05-01 20:34:56    4  False

print(df[df['ccc'].str.contains('A')])
#              DateTime  aaa    bbb   ccc
# 0 2020-05-01 12:34:56    1   True  xyzA
# 3 2020-05-01 20:34:56    4  False  xzyA

大文字・小文字の区分を無くして、特定文字を抽出

str.contains(検索文字, case=False)のようにcase=Falseを指定すると大文字・小文字の区分なく検索します。

df = pd.DataFrame(
    [
        ["2020/05/01 12:34:56",1,True,"xyzA"],
        ["2020/05/01 12:34:56",1,True,"yyzB"],
        ["2020/05/01 16:34:56",1,False,"zzzC"],
        ["2020/05/01 20:34:56",4,False,"xzyA"],
    ], 
    columns = ["DateTime", "aaa", "bbb", "ccc"]
)
df['DateTime'] = pd.to_datetime(df['DateTime'])
print(df)
#              DateTime  aaa    bbb
# 0 2020-05-01 12:34:56    1   True
# 1 2020-05-01 12:34:56    2   True
# 2 2020-05-01 16:34:56    1   True
# 3 2020-05-01 20:34:56    4  False

print(df[df['ccc'].str.contains('a', case=False)])
#              DateTime  aaa    bbb   ccc
# 0 2020-05-01 12:34:56    1   True  xyzA
# 3 2020-05-01 20:34:56    4  False  xzyA

前方一致

str.startswith(検索文字)で前方一致にて抽出することができます。

ただし、str.containsのようにcaseは使用できませんので注意してください。

df = pd.DataFrame(
    [
        ["2020/05/01 12:34:56",1,True,"xyzA"],
        ["2020/05/01 12:34:56",1,True,"yyzB"],
        ["2020/05/01 16:34:56",1,False,"zzzC"],
        ["2020/05/01 20:34:56",4,False,"xzyA"],
    ], 
    columns = ["DateTime", "aaa", "bbb", "ccc"]
)
df['DateTime'] = pd.to_datetime(df['DateTime'])
print(df)
#              DateTime  aaa    bbb
# 0 2020-05-01 12:34:56    1   True
# 1 2020-05-01 12:34:56    2   True
# 2 2020-05-01 16:34:56    1   True
# 3 2020-05-01 20:34:56    4  False

print(df[df['ccc'].str.startswith('x')])
#              DateTime  aaa    bbb   ccc
# 0 2020-05-01 12:34:56    1   True  xyzA
# 3 2020-05-01 20:34:56    4  False  xzyA

後方一致

str.sendswith(検索文字)で後方一致にて抽出することができます。

ただし、str.containsのようにcaseは使用できませんので注意してください。

df = pd.DataFrame(
    [
        ["2020/05/01 12:34:56",1,True,"xyzA"],
        ["2020/05/01 12:34:56",1,True,"yyzB"],
        ["2020/05/01 16:34:56",1,False,"zzzC"],
        ["2020/05/01 20:34:56",4,False,"xzyA"],
    ], 
    columns = ["DateTime", "aaa", "bbb", "ccc"]
)
df['DateTime'] = pd.to_datetime(df['DateTime'])
print(df)
#              DateTime  aaa    bbb
# 0 2020-05-01 12:34:56    1   True
# 1 2020-05-01 12:34:56    2   True
# 2 2020-05-01 16:34:56    1   True
# 3 2020-05-01 20:34:56    4  False

print(df[df['ccc'].str.endswith('A')])
#              DateTime  aaa    bbb   ccc
# 0 2020-05-01 12:34:56    1   True  xyzA
# 3 2020-05-01 20:34:56    4  False  xzyA

 

正規表現

str.match(正規表現)にて抽出することが可能です。

df = pd.DataFrame(
    [
        ["2020/05/01 12:34:56",1,True,"xyzA"],
        ["2020/05/01 12:34:56",1,True,"yyzB"],
        ["2020/05/01 16:34:56",1,False,"zzzC"],
        ["2020/05/01 20:34:56",4,False,"xzyA"],
    ], 
    columns = ["DateTime", "aaa", "bbb", "ccc"]
)
df['DateTime'] = pd.to_datetime(df['DateTime'])
print(df)
#              DateTime  aaa    bbb
# 0 2020-05-01 12:34:56    1   True
# 1 2020-05-01 12:34:56    2   True
# 2 2020-05-01 16:34:56    1   True
# 3 2020-05-01 20:34:56    4  False

print(df[df['ccc'].str.match('\D*A$')])
#              DateTime  aaa    bbb   ccc
# 0 2020-05-01 12:34:56    1   True  xyzA
# 3 2020-05-01 20:34:56    4  False  xzyA

 

日付

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

print(df)
#                            bbb    ccc
# Date Time                            
# 2020-04-01 12:34:56+00:00    1   True
# 2020-05-01 16:34:56+00:00    4  False
                     
    
print(df[df.index > "2020/05/01"])
#                            bbb    ccc
# Date Time                            
# 2020-05-01 16:34:56+00:00    4  False


# 期間で抽出
print(df[(df.index >= "2020/05/01") & (df.index < "2020/06/01")])
#                            bbb    ccc
# Date Time                            
# 2020-05-01 16:34:56+00:00    4  False
今回はインデックスで抽出していますが、日時型であれば問題ないです。

Nan

df = pd.DataFrame([[1,2,3],[4,np.nan,6],[7,8,9]], columns = ["aaa", "bbb", "ccc"])

print(df)
#    aaa  bbb  ccc
# 0    1  2.0    3
# 1    4  NaN    6
# 2    7  8.0    9

print(df[df['bbb'].isna() == True])
#    aaa  bbb  ccc
# 1    4  NaN    6

print(df[df['bbb'].isna() == False])
#    aaa  bbb  ccc
# 0    1  2.0    3
# 2    7  8.0    9

 

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