このトピックでは、DataFrame API を呼び出して列操作を実行する方法について説明します。
列操作
from odps.df import DataFrame
iris = DataFrame(o.get_table('pyodps_iris'))
lens = DataFrame(o.get_table('pyodps_ml_100k_lens'))シーケンスオブジェクトに定数を加算したり、sin 関数を実行したりすると、シーケンスオブジェクトのすべての要素に定数が加算されたり、sin 関数が実行されたりします。
NULL 関連関数
DataFrame API は、isnull、notnull、fillna などの NULL 関連のビルトイン関数を備えています。isnull 関数を使用すると、フィールドの値が NULL かどうかを確認できます。notnull 関数を使用すると、フィールドの値が NULL でないかどうかを確認できます。fillna 関数を使用すると、NULL 値を指定した値に置き換えることができます。
>>> iris.sepallength.isnull().head(5)
sepallength
0 False
1 False
2 False
3 False
4 False論理関数
ifelse は BOOLEAN 型のフィールドに適用されます。条件が真の場合、最初のパラメーターを返します。それ以外の場合、2 番目のパラメーターを返します。
>>> (iris.sepallength > 5).ifelse('gt5', 'lte5').rename('cmp5').head(5)
cmp5
0 gt5
1 lte5
2 lte5
3 lte5
4 lte5switch 関数を使用すると、複数の条件を処理できます。
>>> iris.sepallength.switch(4.9, 'eq4.9', 5.0, 'eq5.0', default='noeq').rename('equalness').head(5)
equalness
0 noeq
1 eq4.9
2 noeq
3 noeq
4 eq5.0>>> from odps.df import switch
>>> switch(iris.sepallength == 4.9, 'eq4.9', iris.sepallength == 5.0, 'eq5.0', default='noeq').rename('equalness').head(5)
equalness
0 noeq
1 eq4.9
2 noeq
3 noeq
4 eq5.0MaxCompute 上の Python(PyODPS)V0.7.8 以後では、指定された条件に基づいてデータセットの列の値を変更できます。
>>> iris[iris.sepallength > 5, 'cmp5'] = 'gt5'
>>> iris[iris.sepallength <= 5, 'cmp5'] = 'lte5'
>>> iris.head(5)
cmp5
0 gt5
1 lte5
2 lte5
3 lte5
4 lte5算術演算
数値フィールドでは、シーケンスオブジェクトは、加算(+)、減算(-)、乗算(*)、除算(/)などの算術演算をサポートしています。 log 関数と sin 関数もサポートされています。
>>> (iris.sepallength * 10).log().head(5)
sepallength
0 3.931826
1 3.891820
2 3.850148
3 3.828641
4 3.912023>>> fields = [iris.sepallength,
>>> (iris.sepallength / 2).rename('sepallength divided by 2'),
>>> (iris.sepallength ** 2).rename('sepallength squared')]
>>> iris[fields].head(5)
sepallength sepallength divided by 2 sepallength squared
0 5.1 2.55 26.01
1 4.9 2.45 24.01
2 4.7 2.35 22.09
3 4.6 2.30 21.16
4 5.0 2.50 25.00次の表に、サポートされている算術演算を示します。
算術演算 | 説明 |
abs | 指定された数値の絶対値を返します。 |
sqrt | 指定された数値の平方根を返します。 |
sin | 該当なし |
sinh | 該当なし |
cos | 該当なし |
cosh | 該当なし |
tan | 該当なし |
tanh | 該当なし |
arccos | 該当なし |
arccosh | 該当なし |
arcsin | 該当なし |
arcsinh | 該当なし |
arctan | 該当なし |
arctanh | 該当なし |
exp | 指定された数値の累乗になる e を返します。 |
expm1 | 指定された数値の累乗になる e から 1 を引いた値を返します。 |
log | 指定された底を使用して、指定された数値の対数を返します。 |
log2 | 該当なし |
log10 | 該当なし |
log1p | log(1+x) |
radians | ラジアンの値を度に変換します。 |
degrees | 度の値をラジアンに変換します。 |
ceil | 指定された数値以上の最小の整数を返します。 |
floor | 指定された数値以下の最大の整数を返します。 |
trunc | 指定された小数点以下に切り捨てられた数値を返します。 |
シーケンスオブジェクトを別のシーケンスオブジェクトまたはスカラーオブジェクトと比較できます。
>>> (iris.sepallength < 5).head(5)
sepallength
0 False
1 True
2 True
3 True
4 FalseDataFrame API は、3 <= iris.sepallength <= 5 などの順次比較をサポートしていません。ただし、between 関数を使用して、iris.sepallength の値が指定された間隔内にあるかどうかを確認できます。
>>> (iris.sepallength.between(3, 5)).head(5)
sepallength
0 False
1 True
2 True
3 True
4 Trueデフォルトでは、between 関数はエンドポイントを含む間隔を指定します。開区間を指定するには、inclusive パラメーターを False に設定します。
>>> (iris.sepallength.between(3, 5, inclusive=False)).head(5)
sepallength
0 False
1 True
2 True
3 True
4 False文字列関連操作
DataFrame API は、シーケンスオブジェクトまたはスカラーオブジェクトに対して、多数の文字列関連操作を提供します。
>>> fields = [
>>> iris.name.upper().rename('upper_name'),
>>> iris.name.extract('Iris(.*)', group=1)
>>> ]
>>> iris[fields].head(5)
upper_name name
0 IRIS-SETOSA -setosa
1 IRIS-SETOSA -setosa
2 IRIS-SETOSA -setosa
3 IRIS-SETOSA -setosa
4 IRIS-SETOSA -setosa次の表に、文字列関連の操作を示します。
操作 | 説明 |
capitalize | 該当なし |
contains | 指定された文字列に部分文字列が含まれているかどうかを返します。 |
count | 指定された文字列の出現回数を返します。 |
endswith | 指定された文字列で指定された文字列を終了します。 |
startswith | 指定された文字列で指定された文字列を開始します。 |
extract | 正規表現を抽出します。 group が指定されていない場合、正規表現のパターンを満たす部分文字列が返されます。 group が指定されている場合、指定された group が返されます。 |
find | 左から右に検索し、指定された部分文字列が最初に出現した位置を返します。一致する部分文字列が存在しない場合は、値 -1 が返されます。 |
rfind | 右から左に検索し、指定された部分文字列が最初に出現した位置を返します。一致する部分文字列が存在しない場合は、値 -1 が返されます。 |
replace | 正規表現のパターンを満たす部分文字列を別の部分文字列に置き換えます。 n パラメーターを指定すると、部分文字列は n 回置き換えられます。 |
get | 指定された位置の文字列を返します。 |
len | 指定された文字列の長さを返します。 |
ljust |
|
rjust |
|
lower | 指定された文字列を小文字に変換します。 |
upper | 指定された文字列を大文字に変換します。 |
lstrip | 指定された文字列の左側のスペース(空白行を含む)を削除します。 |
rstrip | 指定された文字列の右側のスペース(空白行を含む)を削除します。 |
strip | 指定された文字列の両側のスペース(空白行を含む)を削除します。 |
split | 指定されたデリミタで指定された文字列を分割し、LIST<STRING> 型の値を返します。 |
pad | 指定された位置(文字列の左側、右側、または両側)に |
repeat | n 回繰り返します。 |
slice | スライス操作を実行します。 |
swapcase | 指定された文字列内のすべての大文字を小文字に変換し、すべての小文字を大文字に変換します。 |
title | 単語が大文字で始まり、残りの文字が小文字である、指定された文字列のタイトルケースバージョンを返します。この操作は、 |
zfill | 文字列が |
isalnum | 指定された文字列のすべての文字が英数字である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isalpha | 指定された文字列のすべての文字がアルファベットである場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isdigit | 指定された文字列のすべての文字が数字である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isspace | 指定された文字列のすべての文字がスペースである場合は True を返します。それ以外の場合は、False が返されます。この操作は |
islower | 指定された文字列の大文字と小文字が区別されるすべての文字が小文字である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isupper | 指定された文字列の大文字と小文字が区別されるすべての文字が大文字である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
istitle | 指定された文字列がタイトルケースの文字列である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isnumeric | 指定された文字列のすべての文字が数字である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
isdecimal | 指定された文字列のすべての文字が10進数である場合は True を返します。それ以外の場合は、False が返されます。この操作は |
todict | 指定されたデリミタで指定された文字列を辞書に分割し、DICT<STRING, STRING> 型の値を返します。2 つの入力パラメーターは、プロジェクトデリミタとキーと値のデリミタです。 |
strptime | 時刻を表す指定された文字列を指定された形式に変換します。時刻形式は、標準 Python ライブラリの時間形式と同じです。 Python の時刻形式の詳細については、「日付と時刻の基本型」をご参照ください。 |
時間関連操作
時間関連のビルトイン関数を呼び出して、DATETIME 型のシーケンスオブジェクトまたはスカラーオブジェクトを管理できます。
>>> df = lens[[lens.unix_timestamp.astype('datetime').rename('dt')]]
>>> df[df.dt,
>>> df.dt.year.rename('year'),
>>> df.dt.month.rename('month'),
>>> df.dt.day.rename('day'),
>>> df.dt.hour.rename('hour')].head(5)
dt year month day hour
0 1998-04-08 11:02:00 1998 4 8 11
1 1998-04-08 10:57:55 1998 4 8 10
2 1998-04-08 10:45:26 1998 4 8 10
3 1998-04-08 10:25:52 1998 4 8 10
4 1998-04-08 10:44:19 1998 4 8 10次の表に、時間関連の属性を示します。
時間関連属性 | 説明 |
year | 該当なし |
month | 該当なし |
day | 該当なし |
hour | 該当なし |
minute | 該当なし |
second | 該当なし |
weekofyear | 指定された日付が含まれる年の週を表す数値を返します。月曜日は週の最初の日とみなされます。 |
weekday | 指定された日付が含まれる曜日の数値を返します。 |
dayofweek | 指定された日付が含まれる曜日の数値を返します。 |
strftime | 時刻を表す指定された文字列を指定された形式に変換します。時刻形式は、標準 Python ライブラリの時間形式と同じです。 Python の時刻形式の詳細については、「日付と時刻の基本型」をご参照ください。 |
PyODPS は、時間の加算と減算もサポートしています。たとえば、現在の日付の 3 日前の日付を取得できます。ある日付列を別の日付列から減算して、ミリ秒単位の差分を取得できます。
>>> df
a b
0 2016-12-06 16:43:12.460001 2016-12-06 17:43:12.460018
1 2016-12-06 16:43:12.460012 2016-12-06 17:43:12.460021
2 2016-12-06 16:43:12.460015 2016-12-06 17:43:12.460022
>>> from odps.df import day
>>> df.a - day(3)
a
0 2016-12-03 16:43:12.460001
1 2016-12-03 16:43:12.460012
2 2016-12-03 16:43:12.460015
>>> (df.b - df.a).dtype
int64
>>> (df.b - df.a).rename('a')
a
0 3600000
1 3600000
2 3600000次の表に、サポートされている DATETIME 型を示します。
型 | 説明 |
year | 該当なし |
month | 該当なし |
day | 該当なし |
hour | 該当なし |
minute | 該当なし |
second | 該当なし |
millisecond | 該当なし |
コレクション関連操作
PyODPS は、LIST 型と DICT 型のコレクションをサポートしています。添え字を使用して、どちらの型からもアイテムを取得できます。また、len メソッドを使用して、各コレクション内のアイテム数を取得することもできます。
さらに、LIST 型と DICT 型のコレクションは、explode メソッドをサポートしています。 explode メソッドを使用して、コレクションの内容を表示できます。 LIST 型のコレクションの場合、explode メソッドはデフォルトで 1 つの列を返します。pos パラメーターを True に設定すると、explode メソッドは 2 つの列を返します。列の 1 つは、配列内の各値のシリアル番号を示します。 explode メソッドは、Python の enumerate メソッドに似ています。 DICT 型のコレクションの場合、explode メソッドは 2 つの列を返します。2 つの列は、それぞれキーと値を示します。生成される列の名前として、列名を explode メソッドに渡すことができます。
次の例は、explode メソッドの使用方法を示しています。
>>> df
id a b
0 1 [a1, b1] {'a2': 0, 'b2': 1, 'c2': 2}
1 2 [c1] {'d2': 3, 'e2': 4}
>>> df[df.id, df.a[0], df.b['b2']]
id a b
0 1 a1 1
1 2 c1 NaN
>>> df[df.id, df.a.len(), df.b.len()]
id a b
0 1 2 3
1 2 1 2
>>> df.a.explode()
a
0 a1
1 b1
2 c1
>>> df.a.explode(pos=True)
a_pos a
0 0 a1
1 1 b1
2 0 c1
>>> # 列名を指定します。
>>> df.a.explode(['pos', 'value'], pos=True)
pos value
0 0 a1
1 1 b1
2 0 c1
>>> df.b.explode()
b_key b_value
0 a2 0
1 b2 1
2 c2 2
3 d2 3
4 e2 4
>>> # 列名を指定します。
>>> df.b.explode(['key', 'value'])
key value
0 a2 0
1 b2 1
2 c2 2
3 d2 3
4 e2 4explode メソッドを コレクション と一緒に使用できます。このようにして、explode メソッドによって生成された列は、元の列と結合されます。
>>> df[df.id, df.a.explode()]
id a
0 1 a1
1 1 b1
2 2 c1
>>> df[df.id, df.a.explode(), df.b.explode()]
id a b_key b_value
0 1 a1 a2 0
1 1 a1 b2 1
2 1 a1 c2 2
3 1 b1 a2 0
4 1 b1 b2 1
5 1 b1 c2 2
6 2 c1 d2 3
7 2 c1 e2 4len メソッドと explode メソッドに加えて、LIST 型のコレクションは次の 2 つのメソッドをサポートしています。
メソッド | 説明 |
contains(v) | 指定されたリストに指定された要素が含まれているかどうかを確認します。 |
sort | 指定されたリストをソートし、LIST 型の値を返します。 |
DICT 型のコレクションも次の 2 つのメソッドをサポートしています。
メソッド | 説明 |
keys | DICT キーを取得し、LIST 型の値を返します。 |
values | DICT 値を取得し、LIST 型の値を返します。 |
その他の操作
isin 操作を使用して、シーケンスオブジェクトの要素が指定されたコレクションに存在するかどうかを確認できます。notin 操作を使用して、シーケンスオブジェクトの要素が指定されたコレクションに存在しないかどうかを確認できます。
>>> iris.sepallength.isin([4.9, 5.1]).rename('sepallength').head(5)
sepallength
0 True
1 True
2 False
3 False
4 Falsecut 操作を使用して、シーケンスオブジェクトのデータを複数のセグメントに分割できます。
>>> iris.sepallength.cut(range(6), labels=['0-1', '1-2', '2-3', '3-4', '4-5']).rename('sepallength_cut').head(5)
sepallength_cut
0 None
1 4-5
2 4-5
3 4-5
4 4-5include_under 操作と include_over 操作を使用して、それぞれ最大値と最小値を指定できます。
>>> labels = ['0-1', '1-2', '2-3', '3-4', '4-5', '5-']
>>> iris.sepallength.cut(range(6), labels=labels, include_over=True).rename('sepallength_cut').head(5)
sepallength_cut
0 5-
1 4-5
2 4-5
3 4-5
4 4-5MaxCompute でビルトイン関数または UDF を呼び出す
MaxCompute でビルトイン関数またはユーザー定義関数(UDF)を呼び出して列を作成するには、func 関数を使用できます。 func 関数の戻り値は、デフォルトでは STRING 型です。rtype パラメーターを使用して、戻り値の型を指定できます。
>>> from odps.df import func
>>>
>>> iris[iris.name, func.rand(rtype='float').rename('rand')][:4]
>>> iris[iris.name, func.rand(10, rtype='float').rename('rand')][:4]
>>> # MaxCompute で定義された UDF を呼び出します。列名を自動的に判別できない場合は、列名を指定する必要があります。
>>> iris[iris.name, func.your_udf(iris.sepalwidth, iris.sepallength, rtype='float').rename('new_col')]
>>> # 他のプロジェクトの UDF を呼び出します。 name パラメーターを使用して列名を指定できます。
>>> iris[iris.name, func.your_udf(iris.sepalwidth, iris.sepallength, rtype='float', project='udf_project', name='new_col')]Pandas バックエンドでは、func 関数を含む式を実行することはできません。