このトピックでは、DataFrame オブジェクトを作成および管理する方法と、DataFrame を使用してデータを処理する方法について説明します。
データの準備
このトピックでは、u.user、u.item、および u.data を例として使用します。 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 'タイムスタンプ' )
コマンドを実行して、ファイルのデータを MaxCompute テーブルにインポートします。トンネルコマンドの詳細については、 をご参照ください。トンネルアップロードコマンドを使用して、ファイルのデータを MaxCompute テーブルにインポートします。Tunnel コマンドの詳細については、「トンネル コマンド。
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(映画関連データ)、pyodps_ml_100k_users(ユーザー関連データ)、pyodps_ml_100k_ratings(評価関連データ)の各テーブルを使用します。次の例は、IPython でこれらのテーブルに対して操作を実行する方法を示しています。
IPython を使用する前に、Python がインストールされていることを確認してください。 IPython は Python をベースに開発されています。 Python 環境をインストールする必要があります。 Python 環境がインストールされた後、pip install IPython を使用して IPython をインストールできます。インストールが完了したら、IPython コマンドを実行して、IPython ベースのインタラクティブ環境を起動できます。その後、Python コードを作成して実行できます。
MaxCompute オブジェクトを作成します。
import os from odps import ODPS # 環境変数 ALIBABA_CLOUD_ACCESS_KEY_ID を Alibaba Cloud アカウントの AccessKey ID に設定します。 # 環境変数 ALIBABA_CLOUD_ACCESS_KEY_SECRET を Alibaba Cloud アカウントの AccessKey シークレットに設定します。 # AccessKey ID または AccessKey シークレットを直接使用しないことをお勧めします。 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プロパティをクエリして、DataFrame オブジェクトのフィールドとフィールドのデータ型を表示します。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の場合、sex_bool を True に設定します。 sex の値が M でない場合は、sex_bool を 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 313 つのテーブルを
結合し、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 ideo_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 ノードが使用されています。詳細については、「PyODPS 3 タスクの開発」をご参照ください。
テストデータを格納するためのテーブルを作成します。
DataWorks のテーブル管理機能を使用してテーブルを作成します。
テーブル編集ページの左上隅にある
アイコンをクリックします。次のステートメントを実行してテーブルを作成します。
CREATE TABLE pyodps_iris ( sepallength double COMMENT 'がく片の長さ (cm)', sepalwidth double COMMENT 'がく片の幅 (cm)', petallength double COMMENT '花びらの長さ (cm)', petalwidth double COMMENT '花びらの幅 (cm)', name string COMMENT '名前' ) ;
テストデータをアップロードします。
作成したテーブルの名前を右クリックし、[データのインポート] を選択します。 [データインポートウィザード] ダイアログボックスで、[データのインポート][データインポートウィザード] をクリックします。次に、 をクリックして、ダウンロードしたデータセットをアップロードします。

[場所別に一致] を選択し、[インポート データ] をクリックします。
目的のワークフローをクリックし、MaxCompute を右クリックして、[ノードの作成] > [PyODPS 3] を選択し、コードを保存して実行するための PyODPS ノードを作成します。
コードを記述し、
アイコンをクリックします。下部ペインの [ランタイムログ] セクションで結果を確認できます。コードの詳細:from odps import ODPS from odps.df import DataFrame, output import os # ALIBABA_CLOUD_ACCESS_KEY_ID 環境変数がユーザーの AccessKey ID に設定され、 # ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数がユーザーの AccessKey シークレットに設定されていることを確認します。 # AccessKey ID と AccessKey シークレットの文字列を直接使用することはお勧めしません。 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 テーブルから DataFrame オブジェクト iris を作成します。 iris = DataFrame(o.get_table('pyodps_iris')) print(iris.head(10)) # iris コンテンツの一部を表示します。 print(iris.sepallength.head(5)) # ユーザー定義関数を使用して、iris の 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