O DataFrame oferece uma API de dados estruturados para o MaxCompute. Este tópico orienta você na criação de objetos DataFrame e na execução de operações comuns com dados, como filtragem, agregação e joins.
Preparação dos dados
Os exemplos utilizam os arquivos u.user, u.item e u.data, que contêm dados de usuários, filmes e avaliações, respectivamente.
-
Crie as tabelas:
-
Tabela
pyodps_ml_100k_userspara dados de usuários.CREATE TABLE IF NOT EXISTS pyodps_ml_100k_users ( user_id BIGINT COMMENT 'User ID', age BIGINT COMMENT 'Age', sex STRING COMMENT 'Gender', occupation STRING COMMENT 'Occupation', zip_code STRING COMMENT 'Zip code' ); -
Tabela
pyodps_ml_100k_moviespara dados de filmes.CREATE TABLE IF NOT EXISTS pyodps_ml_100k_movies ( movie_id BIGINT COMMENT 'Movie ID', title STRING COMMENT 'Movie title', release_date STRING COMMENT 'Release date', video_release_date STRING COMMENT 'Video release date', IMDb_URL STRING COMMENT 'IMDb URL', unknown TINYINT COMMENT 'Unknown', Action TINYINT COMMENT 'Action', Adventure TINYINT COMMENT 'Adventure', Animation TINYINT COMMENT 'Animation', Children TINYINT COMMENT 'Children', Comedy TINYINT COMMENT 'Comedy', Crime TINYINT COMMENT 'Crime', Documentary TINYINT COMMENT 'Documentary', Drama TINYINT COMMENT 'Drama', Fantasy TINYINT COMMENT 'Fantasy', FilmNoir TINYINT COMMENT 'Film Noir', Horror TINYINT COMMENT 'Horror', Musical TINYINT COMMENT 'Musical', Mystery TINYINT COMMENT 'Mystery', Romance TINYINT COMMENT 'Romance', SciFi TINYINT COMMENT 'Sci-Fi', Thriller TINYINT COMMENT 'Thriller', War TINYINT COMMENT 'War', Western TINYINT COMMENT 'Western' ); -
Tabela
pyodps_ml_100k_ratingspara dados de avaliações.CREATE TABLE IF NOT EXISTS pyodps_ml_100k_ratings ( user_id BIGINT COMMENT 'User ID', movie_id BIGINT COMMENT 'Movie ID', rating BIGINT COMMENT 'Rating', timestamp BIGINT COMMENT 'Timestamp' )
-
-
Use o Tunnel Upload para importar arquivos de dados locais para as tabelas do MaxCompute. Para obter mais informações sobre as operações do Tunnel, consulte 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;
Operações com DataFrame
Com as três tabelas prontas — pyodps_ml_100k_movies, pyodps_ml_100k_users e pyodps_ml_100k_ratings —, explore as operações de DataFrame no IPython.
O IPython requer Python. Execute pip install IPython para instalá-lo e, em seguida, execute ipython para iniciar o ambiente interativo.
-
Crie um objeto ODPS.
import os from odps import ODPS # Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is set to your Access Key ID, # and the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is set to your Access Key Secret. # We recommend that you avoid hardcoding the Access Key ID and Access Key Secret in your code. o = ODPS( os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'), os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'), project='your-default-project', endpoint='your-end-point', ) -
Crie um objeto DataFrame a partir de uma tabela.
from odps.df import DataFrame users = DataFrame(o.get_table('pyodps_ml_100k_users')); -
Visualize os nomes das colunas e os tipos de dados com a propriedade
dtypes.print(users.dtypes)Saída:
odps.Schema { user_id int64 age int64 sex string occupation string zip_code string } -
Visualize as primeiras N linhas com o método
head.print(users.head(10))Saída:
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 -
Para trabalhar com colunas específicas, use um dos métodos a seguir:
-
Selecione um subconjunto de colunas.
print(users[['user_id', 'age']].head(5))Saída:
user_id age 0 1 24 1 2 53 2 3 23 3 4 24 4 5 33 -
Exclua colunas específicas.
print(users.exclude('zip_code', 'age').head(5))Saída:
user_id sex occupation 0 1 M technician 1 2 F other 2 3 M writer 3 4 M technician 4 5 F other -
Exclua colunas e adicione colunas calculadas. Por exemplo, crie uma coluna booleana chamada
sex_boolque seja True sesexforMe False caso contrário.print(users.select(users.exclude('zip_code', 'sex'), sex_bool=users.sex == 'M').head(5))Saída:
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
-
-
Conte os usuários do sexo masculino e feminino.
print(users.groupby(users.sex).agg(count=users.count()))Saída:
sex count 0 F 273 1 M 670 -
Agrupe os usuários por ocupação, ordene-os em ordem decrescente e visualize as 10 principais ocupações por contagem.
df = users.groupby('occupation').agg(count=users['occupation'].count()) df1 = df.sort(df['count'], ascending=False) print(df1.head(10))Saída:
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 31Você também pode usar o método
value_countspara uma sintaxe mais curta. O número de linhas retornadas é limitado poroptions.df.odps.sort.limit. Para obter mais informações, consulte Configuration.df = users.occupation.value_counts()[:10] print(df.head(10))Saída:
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 -
Faça o join das três tabelas com
joine salve o resultado em uma nova tabela chamada 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)Saída:
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 } -
Crie uma tabela de dados de teste.
Crie uma tabela no DataWorks:
No painel Business Flow, clique com o botão direito em MaxCompute e selecione Create Table. Na caixa de diálogo Create Table, selecione um Path, insira um Name e clique em Create para acessar o editor de tabelas.
Clique em DDL
no canto superior esquerdo da página de edição.-
Insira a seguinte instrução DDL e execute-a para criar a tabela.
CREATE TABLE pyodps_iris ( sepallength double COMMENT 'sepal length (cm)', sepalwidth double COMMENT 'sepal width (cm)', petallength double COMMENT 'petal length (cm)', petalwidth double COMMENT 'petal width (cm)', name string COMMENT 'name' ) ;
-
Carregue os dados de teste.
-
Clique com o botão direito na nova tabela, selecione Import Data e clique em Next para carregar o conjunto de dados baixado.
Na caixa de diálogo Import Data, defina Data Import Method como Upload Local File e File Format como CSV. Selecione o arquivo iris.csv baixado. Defina Delimiter como Comma, Source Charset como GBK e Start Row como 1. Selecione Yes para First Row Is Header. Após confirmar que a visualização dos dados está correta, clique em Next.
Clique em Match by Position para importar os dados.
-
No painel Business Flow, clique com o botão direito em MaxCompute, selecione Create Node e, em seguida, selecione PyODPS 3 para criar um nó PyODPS destinado a armazenar e executar seu código.
-
Insira o código e clique no ícone Run
. Após a execução do código, visualize os resultados na aba Run log abaixo. O código é o seguinte:from odps import ODPS from odps.df import DataFrame, output import os # Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is set to your Access Key ID, # and the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is set to your Access Key Secret. # We recommend that you avoid hardcoding the Access Key ID and Access Key Secret in your code. o = ODPS( os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'), os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'), project='your-default-project', endpoint='your-end-point', ) # Create a DataFrame object named iris from the MaxCompute table. iris = DataFrame(o.get_table('pyodps_iris')) print(iris.head(10)) # Print part of the iris DataFrame. print(iris.sepallength.head(5)) # Use a custom function to calculate the sum of two columns in the iris DataFrame. print(iris.apply(lambda row: row.sepallength + row.sepalwidth, axis=1, reduce=True, types='float').rename('sepaladd').head(3)) # Specify the output names and types for the function. @output(['iris_add', 'iris_sub'], ['float', 'float']) def handle(row): # Use the yield keyword to return multiple output rows. yield row.sepallength - row.sepalwidth, row.sepallength + row.sepalwidth yield row.petallength - row.petalwidth, row.petallength + row.petalwidth # Print the first 5 rows of the result. axis=1 indicates a row-by-row operation. print(iris.apply(handle, axis=1).head(5))Resultados:
# 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
Processamento de dados com DataFrame
Primeiramente, baixe o conjunto de dados Iris. As etapas a seguir usam um nó PyODPS no DataWorks. Para obter mais informações, consulte Develop a PyODPS 3 task.