このトピックでは、基本的なデータ処理のために DataFrame オブジェクトを作成して使用する方法を説明します。
データの準備
このトピックでは、ユーザー、映画、レーティングのデータをそれぞれ含む u.user、u.item、u.data ファイルを使用します。
-
テーブルを作成します:
-
ユーザーデータ用の
pyodps_ml_100k_usersテーブル。CREATE TABLE IF NOT EXISTS pyodps_ml_100k_users ( user_id BIGINT COMMENT 'ユーザー ID', age BIGINT COMMENT '年齢', sex STRING COMMENT '性別', occupation STRING COMMENT '職業', zip_code STRING COMMENT '郵便番号' ); -
映画データ用の
pyodps_ml_100k_moviesテーブル。CREATE TABLE IF NOT EXISTS pyodps_ml_100k_movies ( movie_id BIGINT COMMENT '映画 ID', title STRING COMMENT '映画のタイトル', release_date STRING COMMENT 'リリース日', video_release_date STRING COMMENT 'ビデオリリース日', IMDb_URL STRING COMMENT 'IMDb URL', unknown TINYINT COMMENT '不明', Action TINYINT COMMENT 'アクション', Adventure TINYINT COMMENT 'アドベンチャー', Animation TINYINT COMMENT 'アニメーション', Children TINYINT COMMENT '子供向け', Comedy TINYINT COMMENT 'コメディ', Crime TINYINT COMMENT '犯罪', Documentary TINYINT COMMENT 'ドキュメンタリー', Drama TINYINT COMMENT 'ドラマ', Fantasy TINYINT COMMENT 'ファンタジー', FilmNoir TINYINT COMMENT 'フィルムノワール', Horror TINYINT COMMENT 'ホラー', Musical TINYINT COMMENT 'ミュージカル', Mystery TINYINT COMMENT 'ミステリー', Romance TINYINT COMMENT 'ロマンス', SciFi TINYINT COMMENT 'SF', Thriller TINYINT COMMENT 'スリラー', War TINYINT COMMENT '戦争', Western TINYINT COMMENT '西部劇' ); -
レーティングデータ用の
pyodps_ml_100k_ratingsテーブル。CREATE TABLE IF NOT EXISTS pyodps_ml_100k_ratings ( user_id BIGINT COMMENT 'ユーザー ID', movie_id BIGINT COMMENT '映画 ID', rating BIGINT COMMENT 'レーティング', timestamp BIGINT COMMENT 'タイムスタンプ' )
-
-
Tunnel アップロード を使用して、ローカルのデータファイルを MaxCompute テーブルにインポートします。Tunnel の操作の詳細については、「Tunnel Commands」をご参照ください。
Tunnel upload -fd | path_to_file/u.user pyodps_ml_100k_users; Tunnel upload -fd | path_to_file/u.item pyodps_ml_100k_movies; Tunnel upload -fd | path_to_file/u.data pyodps_ml_100k_ratings;
DataFrame の操作
これで、pyodps_ml_100k_movies (movies)、pyodps_ml_100k_users (users)、pyodps_ml_100k_ratings (ratings) の 3 つのテーブルが作成されました。次の例は IPython で実行します。
Python がインストールされていることを確認してください。IPython は Python 上に構築されているため、Python 環境が必要です。次に、pip install IPython を実行します。その後、ipython コマンドを実行してインタラクティブ環境を起動し、Python コードの作成と実行を開始します。
-
ODPS オブジェクトを作成します。
import os from odps import ODPS # ALIBABA_CLOUD_ACCESS_KEY_ID 環境変数にアクセスキー ID が設定されていること、 # および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数にシークレットアクセスキーが設定されていることを確認してください。 # コード内にアクセスキー ID とシークレットアクセスキーをハードコーディングしないことを推奨します。 o = ODPS( os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'), os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'), project='your-default-project', endpoint='your-end-point', ) -
テーブルオブジェクトから DataFrame オブジェクトを作成します。
from odps.df import DataFrame users = DataFrame(o.get_table('pyodps_ml_100k_users')); -
dtypesプロパティを使用して、カラムとそのデータ型を確認します。print(users.dtypes)出力:
odps.Schema { user_id int64 age int64 sex string occupation string zip_code string } -
headメソッドを使用して、先頭 N 行をプレビューします。print(users.head(10))出力:
user_id age sex occupation zip_code 0 1 24 M technician 85711 1 2 53 F other 94043 2 3 23 M writer 32067 3 4 24 M technician 43537 4 5 33 F other 15213 5 6 42 M executive 98101 6 7 57 M administrator 91344 7 8 36 M administrator 05201 8 9 29 M student 01002 9 10 53 M lawyer 90703 -
すべてのカラムが不要な場合は、次のいずれかの方法を使用します:
-
カラムのサブセットを選択します。
print(users[['user_id', 'age']].head(5))出力:
user_id age 0 1 24 1 2 53 2 3 23 3 4 24 4 5 33 -
特定のカラムを除外します。
print(users.exclude('zip_code', 'age').head(5))出力:
user_id sex occupation 0 1 M technician 1 2 F other 2 3 M writer 3 4 M technician 4 5 F other -
一部のカラムを除外し、新しい計算列を追加します。たとえば、
sex_boolという名前のブール型のカラムを作成します。このカラムは、sexの値がMの場合は True、それ以外の場合は False になります。print(users.select(users.exclude('zip_code', 'sex'), sex_bool=users.sex == 'M').head(5))出力:
user_id age occupation sex_bool 0 1 24 technician True 1 2 53 other False 2 3 23 writer True 3 4 24 technician True 4 5 33 other False
-
-
男女のユーザー数をカウントします。
print(users.groupby(users.sex).agg(count=users.count()))出力:
sex count 0 F 273 1 M 670 -
職業でユーザーをグループ化し、降順でソートして、件数が多い上位 10 件の職業を確認します。
df = users.groupby('occupation').agg(count=users['occupation'].count()) df1 = df.sort(df['count'], ascending=False) print(df1.head(10))出力:
occupation count 0 student 196 1 other 105 2 educator 95 3 administrator 79 4 engineer 67 5 programmer 66 6 librarian 51 7 writer 45 8 executive 32 9 scientist 31または、より短い構文として
value_countsメソッドを使用します。このメソッドが返す行数は、options.df.odps.sort.limit設定によって制限されます。詳細については、「設定」をご参照ください。df = users.occupation.value_counts()[:10] print(df.head(10))出力:
occupation count 0 student 196 1 other 105 2 educator 95 3 administrator 79 4 engineer 67 5 programmer 66 6 librarian 51 7 writer 45 8 executive 32 9 scientist 31 -
joinを使用して 3 つのテーブルを結合し、結果を pyodps_ml_100k_lens という名前の新しいテーブルに保存します。movies = DataFrame(o.get_table('pyodps_ml_100k_movies')) ratings = DataFrame(o.get_table('pyodps_ml_100k_ratings')) o.delete_table('pyodps_ml_100k_lens', if_exists=True) lens = movies.join(ratings).join(users).persist('pyodps_ml_100k_lens') print(lens.dtypes)出力:
odps.Schema { movie_id int64 title string release_date string video_release_date string imdb_url string unknown int64 action int64 adventure int64 animation int64 children int64 comedy int64 crime int64 documentary int64 drama int64 fantasy int64 filmnoir int64 horror int64 musical int64 mystery int64 romance int64 scifi int64 thriller int64 war int64 western int64 user_id int64 rating int64 timestamp int64 age int64 sex string occupation string zip_code string }
DataFrame のデータ処理
まず、Iris データセットをダウンロードします。このセクションでは、DataWorks の PyODPS ノードを使用します。詳細については、「Develop a PyODPS 3 task」をご参照ください。
-
テストデータテーブルを作成します。
DataWorks でテーブルを作成します:
-
編集ページの左上にある DDL
をクリックします。 -
次の DDL ステートメントを入力し、ステートメントを実行してテーブルを作成します。
CREATE TABLE pyodps_iris ( sepallength double COMMENT 'がくの長さ (cm)', sepalwidth double COMMENT 'がくの幅 (cm)', petallength double COMMENT '花びらの長さ (cm)', petalwidth double COMMENT '花びらの幅 (cm)', name string COMMENT '名前' ) ;
-
-
テストデータをアップロードします。
-
新しいテーブルを右クリックし、データのインポート を選択して、[Next] をクリックし、ダウンロードしたデータセットをアップロードします。
[データのインポート] ダイアログボックスで、Data Import Method を [Upload Local File] に、ファイル形式 を [CSV] に設定します。ダウンロードした iris.csv ファイルを選択します。区切り文字 を [Comma]、Source Charset を [GBK]、Start Row を [1] に設定します。先頭行はヘッダー は [Yes] を選択します。データプレビューが正しいことを確認したら、[Next] をクリックします。
-
Match by Position をクリックしてデータをインポートします。
-
-
[ビジネスフロー] ペインで [MaxCompute] を右クリックし、[Create Node] を選択してから、[PyODPS 3] を選択し、コードを保存して実行するための PyODPS ノードを作成します。
-
コードを入力して実行アイコン
をクリックします。コードの実行後、下部の Run log タブで結果を確認できます。コードは次のとおりです:from odps import ODPS from odps.df import DataFrame, output import os # ALIBABA_CLOUD_ACCESS_KEY_ID 環境変数にアクセスキー ID が設定されていること、 # および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数にシークレットアクセスキーが設定されていることを確認してください。 # コード内にアクセスキー ID とシークレットアクセスキーをハードコーディングしないことを推奨します。 o = ODPS( os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'), os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'), project='your-default-project', endpoint='your-end-point', ) # MaxCompute テーブルから iris という名前の DataFrame オブジェクトを作成します。 iris = DataFrame(o.get_table('pyodps_iris')) print(iris.head(10)) # iris DataFrame の一部を出力します。 print(iris.sepallength.head(5)) # カスタム関数を使用して、iris DataFrame の 2 つのカラムの合計を計算します。 print(iris.apply(lambda row: row.sepallength + row.sepalwidth, axis=1, reduce=True, types='float').rename('sepaladd').head(3)) # 関数の出力名と型を指定します。 @output(['iris_add', 'iris_sub'], ['float', 'float']) def handle(row): # yield キーワードを使用して、複数の出力行を返します。 yield row.sepallength - row.sepalwidth, row.sepallength + row.sepalwidth yield row.petallength - row.petalwidth, row.petallength + row.petalwidth # 結果の先頭 5 行を出力します。axis=1 は行ごとの操作を示します。 print(iris.apply(handle, axis=1).head(5))結果:
# print(iris.head(10)) sepallength sepalwidth petallength petalwidth name 0 4.9 3.0 1.4 0.2 Iris-setosa 1 4.7 3.2 1.3 0.2 Iris-setosa 2 4.6 3.1 1.5 0.2 Iris-setosa 3 5.0 3.6 1.4 0.2 Iris-setosa 4 5.4 3.9 1.7 0.4 Iris-setosa 5 4.6 3.4 1.4 0.3 Iris-setosa 6 5.0 3.4 1.5 0.2 Iris-setosa 7 4.4 2.9 1.4 0.2 Iris-setosa 8 4.9 3.1 1.5 0.1 Iris-setosa 9 5.4 3.7 1.5 0.2 Iris-setosa # print(iris.sepallength.head(5)) sepallength 0 4.9 1 4.7 2 4.6 3 5.0 4 5.4 # print(iris.apply(lambda row: row.sepallength + row.sepalwidth, axis=1, reduce=True, types='float').rename('sepaladd').head(3)) sepaladd 0 7.9 1 7.9 2 7.7 # print(iris.apply(handle,axis=1).head(5)) iris_add iris_sub 0 1.9 7.9 1 1.2 1.6 2 1.5 7.9 3 1.1 1.5 4 1.5 7.7