A API DataFrame do PyODPS oferece suporte a diversas operações com colunas, incluindo tratamento de valores nulos, lógica condicional, matemática, strings, data e hora, coleções e funções personalizadas. As operações em uma sequência são aplicadas elemento a elemento a cada valor da coluna.
Pré-requisitos
Antes de executar os exemplos, inicialize os conjuntos de dados:
from odps.df import DataFrame
iris = DataFrame(o.get_table('pyodps_iris'))
lens = DataFrame(o.get_table('pyodps_ml_100k_lens'))
Funções relacionadas a valores nulos
Três funções integradas lidam com valores nulos: isnull, notnull e fillna.
isnull— retornaTruese o valor do campo for nulo.notnull— retornaTruese o valor do campo não for nulo.fillna— substitui valores nulos pelos valores especificados.
>>> iris.sepallength.isnull().head(5)
sepallength
0 False
1 False
2 False
3 False
4 False
Funções lógicas
ifelse
ifelse aplica-se a campos booleanos. Quando a condição é True, retorna o primeiro argumento; caso contrário, retorna o segundo.
>>> (iris.sepallength > 5).ifelse('gt5', 'lte5').rename('cmp5').head(5)
cmp5
0 gt5
1 lte5
2 lte5
3 lte5
4 lte5
switch
switch lida com múltiplas condições, comparando cada valor com uma sequência de pares condição-resultado e retornando o resultado correspondente. Use o parâmetro default para especificar o valor de fallback quando nenhuma condição for atendida.
>>> 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
Importe switch de odps.df para aplicá-lo como função independente em várias colunas:
>>> from odps.df import switch
>>> switch(iris.sepallength == 4.9, 'eq4.9', # condition 1: exact match 4.9
... iris.sepallength == 5.0, 'eq5.0', # condition 2: exact match 5.0
... default='noeq').rename('equalness').head(5)
equalness
0 noeq
1 eq4.9
2 noeq
3 noeq
4 eq5.0
Atribuição condicional (PyODPS V0.7.8 e posterior)
Modifique os valores das colunas com base em condições usando a sintaxe de atribuição:
>>> iris[iris.sepallength > 5, 'cmp5'] = 'gt5' # set 'gt5' where sepallength > 5
>>> iris[iris.sepallength <= 5, 'cmp5'] = 'lte5' # set 'lte5' where sepallength <= 5
>>> iris.head(5)
cmp5
0 gt5
1 lte5
2 lte5
3 lte5
4 lte5
Operações matemáticas
Sequências numéricas aceitam os operadores aritméticos padrão (+, -, *, /) e um conjunto de funções matemáticas.
>>> (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
A tabela a seguir lista todas as funções matemáticas compatíveis.
|
Função |
Descrição |
|
|
Retorna o valor absoluto. |
|
|
Retorna a raiz quadrada. |
|
|
Retorna o seno. |
|
|
Retorna o seno hiperbólico. |
|
|
Retorna o cosseno. |
|
|
Retorna o cosseno hiperbólico. |
|
|
Retorna a tangente. |
|
|
Retorna a tangente hiperbólica. |
|
|
Retorna o arco cosseno. |
|
|
Retorna o cosseno hiperbólico inverso. |
|
|
Retorna o arco seno. |
|
|
Retorna o seno hiperbólico inverso. |
|
|
Retorna o arco tangente. |
|
|
Retorna a tangente hiperbólica inversa. |
|
|
Retorna e elevado à potência fornecida. |
|
|
Retorna e elevado à potência fornecida, menos 1. |
|
|
Retorna o logaritmo na base fornecida. |
|
|
Retorna o logaritmo na base 2. |
|
|
Retorna o logaritmo na base 10. |
|
|
Retorna log(1 + x). |
|
|
Converte valores em radianos para graus. |
|
|
Converte valores em graus para radianos. |
|
|
Retorna o menor inteiro maior ou igual ao número fornecido. |
|
|
Retorna o maior inteiro menor ou igual ao número fornecido. |
|
|
Retorna o número truncado na casa decimal especificada. |
Comparações e verificações de intervalo
Compare uma sequência com outra sequência ou com um escalar:
>>> (iris.sepallength < 5).head(5)
sepallength
0 False
1 True
2 True
3 True
4 False
Comparações encadeadas como 3 <= iris.sepallength <= 5 não são suportadas. Em vez disso, use between:
>>> iris.sepallength.between(3, 5).head(5) # inclusive by default
sepallength
0 False
1 True
2 True
3 True
4 True
Para excluir os extremos, defina inclusive=False:
>>> iris.sepallength.between(3, 5, inclusive=False).head(5)
sepallength
0 False
1 True
2 True
3 True
4 False
Operações com strings
A API DataFrame fornece mais de 35 funções de string para objetos de sequência e escalares. Acesse as funções diretamente em uma coluna de string, sem importar um namespace separado. O exemplo a seguir mostra upper e extract:
>>> 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
A tabela a seguir descreve todas as funções de string compatíveis.
|
Função |
Descrição |
|
|
Converte o primeiro caractere para maiúsculo e o restante para minúsculo. |
|
|
Verifica se a string contém uma substring. O parâmetro |
|
|
Retorna o número de ocorrências da substring especificada. |
|
|
Verifica se a string termina com o sufixo especificado. |
|
|
Verifica se a string começa com o prefixo especificado. |
|
|
Extrai correspondências de uma expressão regular. Sem o parâmetro |
|
|
Pesquisa da esquerda para a direita e retorna o índice da primeira ocorrência da substring. Retorna |
|
|
Pesquisa da direita para a esquerda e retorna o índice da primeira ocorrência da substring. Retorna |
|
|
Substitui substrings correspondentes a um padrão de expressão regular. Especifique |
|
|
Retorna o caractere na posição especificada. |
|
|
Retorna o comprimento da string. |
|
|
Preenche a string à direita com |
|
|
Preenche a string à esquerda com |
|
|
Converte a string para minúsculas. |
|
|
Converte a string para maiúsculas. |
|
|
Remove espaços em branco à esquerda, incluindo linhas em branco. |
|
|
Remove espaços em branco à direita, incluindo linhas em branco. |
|
|
Remove espaços em branco à esquerda e à direita, incluindo linhas em branco. |
|
|
Divide a string no delimitador especificado e retorna um valor |
|
|
Preenche a string com |
|
|
Repete a string n vezes. |
|
|
Executa uma operação de fatiamento na string. |
|
|
Inverte a caixa de todos os caracteres: maiúsculas tornam-se minúsculas e vice-versa. |
|
|
Converte a string para formato de título, em que cada palavra começa com caractere maiúsculo. Equivalente a |
|
|
Preenche a string com |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Retorna |
|
|
Divide a string em um valor |
|
|
Analisa uma string em um datetime usando os mesmos códigos de formato da biblioteca padrão do Python. Consulte Tipos básicos de data e hora. |
Operações com data e hora
As funções de data e hora aplicam-se a objetos de sequência e escalares do tipo DATETIME.
O exemplo a seguir extrai ano, mês, dia e hora de uma coluna de timestamp unix:
>>> 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
A tabela a seguir descreve os atributos de data e hora compatíveis.
Atributo | Descrição |
| Retorna o componente de ano do datetime. |
| Retorna o componente de mês (1-12). |
| Retorna o dia do mês. |
| Retorna o componente de hora (0-23). |
| Retorna o componente de minuto (0-59). |
| Retorna o componente de segundo (0-59). |
| Retorna o número da semana ISO do ano. Segunda-feira é o primeiro dia da semana. |
| Retorna um número representando o dia da semana da data fornecida. |
| Retorna um número representando o dia da semana da data fornecida. |
| Formata o datetime como string usando os mesmos códigos de formato da biblioteca padrão do Python. Consulte Tipos básicos de data e hora. Converte a string fornecida representando uma hora para o formato especificado. O formato de hora é o mesmo que o da biblioteca padrão do Python. Para obter mais informações sobre os formatos de hora em Python, consulte Tipos básicos de data e hora. Converte a string fornecida representando uma hora para o formato especificado. O formato de hora é o mesmo que o formato de hora na biblioteca padrão do Python. Para obter mais informações sobre os formatos de hora em Python, consulte Tipos básicos de data e hora. |
Aritmética de data e hora
O PyODPS oferece suporte a aritmética de datas. Use os tipos de unidade de data e hora de odps.df para adicionar ou subtrair intervalos de tempo. A subtração de duas colunas datetime retorna a diferença em milissegundos como int64.
>>> from odps.df import day
>>> 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
>>> df.a - day(3) # subtract 3 days from column a
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 # difference between two datetime columns
int64
>>> (df.b - df.a).rename('a') # result is in milliseconds
a
0 3600000
1 3600000
2 3600000
A tabela a seguir lista os tipos de unidade de data e hora disponíveis para aritmética.
|
Tipo |
Descrição |
|
|
Intervalo no nível de ano. |
|
|
Intervalo no nível de mês. |
|
|
Intervalo no nível de dia. |
|
|
Intervalo no nível de hora. |
|
|
Intervalo no nível de minuto. |
|
|
Intervalo no nível de segundo. |
|
|
Intervalo no nível de milissegundo. |
Operações com coleções
O PyODPS oferece suporte aos tipos de coleção LIST e DICT. Use subscritos para recuperar itens individuais e len para obter o número de itens.
>>> 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']] # access by subscript
id a b
0 1 a1 1
1 2 c1 NaN
>>> df[df.id, df.a.len(), df.b.len()] # get collection size
id a b
0 1 2 3
1 2 1 2
explode
Use explode para expandir uma coluna de coleção em linhas individuais, com uma linha por elemento. Esse recurso é útil para agregações ou junções subsequentes que exigem dados planos no nível de linha.
Para colunas LIST, explode retorna uma coluna por padrão. Defina pos=True para também retornar o índice de posição do elemento (semelhante ao enumerate do Python):
>>> df.a.explode()
a
0 a1
1 b1
2 c1
>>> df.a.explode(pos=True) # include position index
a_pos a
0 0 a1
1 1 b1
2 0 c1
>>> df.a.explode(['pos', 'value'], pos=True) # specify column names
pos value
0 0 a1
1 1 b1
2 0 c1
Para colunas DICT, explode retorna duas colunas: chaves e valores.
>>> 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']) # specify column names
key value
0 a2 0
1 b2 1
2 c2 2
3 d2 3
4 e2 4
Combine explode com seleção de colunas para unir colunas expandidas às originais:
>>> 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()] # cross-product of both collections
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 4
Métodos específicos de LIST
Além de len e explode, as colunas LIST oferecem suporte aos seguintes métodos.
|
Método |
Descrição |
|
|
Retorna |
|
|
Ordena a lista e retorna um valor LIST. |
Métodos específicos de DICT
Além de len e explode, as colunas DICT oferecem suporte aos seguintes métodos.
|
Método |
Descrição |
|
|
Retorna todas as chaves como valor LIST. |
|
|
Retorna todos os valores como valor LIST. |
Outras operações
isin e notin
isin verifica se cada elemento existe em uma coleção especificada. notin verifica o oposto.
>>> iris.sepallength.isin([4.9, 5.1]).rename('sepallength').head(5)
sepallength
0 True
1 True
2 False
3 False
4 False
cut
cut divide os valores da sequência em segmentos discretos (bins).
>>> 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-5
Use as operações include_under e include_over para especificar os valores máximo e mínimo, respectivamente.
>>> 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-5
Chamar funções integradas ou UDFs no MaxCompute
Use a função func para chamar funções integradas do MaxCompute ou funções definidas pelo usuário (UDFs) e criar colunas. O tipo de retorno padrão é STRING; use o parâmetro rtype para substituí-lo.
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]
# Call a UDF defined in MaxCompute. Specify the column name if it cannot be inferred automatically.
iris[iris.name, func.your_udf(iris.sepalwidth, iris.sepallength, rtype='float').rename('new_col')]
# Call a UDF from another project using the project parameter.
iris[iris.name, func.your_udf(iris.sepalwidth, iris.sepallength, rtype='float', project='udf_project', name='new_col')]
O backend Pandas não oferece suporte a expressões que contenham a função func.