
O DataProfiler é uma biblioteca Python projetada para facilitar a análise de dados, monitoramento e detecção de dados sensíveis .
Carregando dados com um único comando, a biblioteca formata e carrega arquivos automaticamente em um quadro de dados. Provendo os dados, a biblioteca identifica o esquema, estatística, entidades (PII / NPI) e muito mais. Os perfis de dados podem ser usados em aplicativos ou relatórios a jusante.
Introdução leva apenas algumas linhas de código (Exemplo CSV):
import json
from dataprofiler import Data , Profiler
data = Data ( "your_file.csv" ) # Auto-Detect & Load: CSV, AVRO, Parquet, JSON, Text, URL
print ( data . data . head ( 5 )) # Access data directly via a compatible Pandas DataFrame
profile = Profiler ( data ) # Calculate Statistics, Entity Recognition, etc
readable_report = profile . report ( report_options = { "output_format" : "compact" })
print ( json . dumps ( readable_report , indent = 4 ))Nota: O Profiler de dados vem com um modelo de aprendizado profundo pré-treinado, usado para identificar com eficiência dados sensíveis (PII / NPI). Se desejar, é fácil adicionar novas entidades ao modelo pré-treinado existente ou inserir um novo novo pipeline para reconhecimento de entidades.
Para documentação da API, visite a página de documentação.
Se você tiver sugestões ou encontrar um bug, abra um problema.
Se você deseja contribuir, visite a página contribuinte.
Para instalar o pacote completo da Pypi : pip install DataProfiler[full]
Se você deseja instalar as dependências do ML sem gerar relatórios, use DataProfiler[ml]
Se os requisitos de ML forem muito rigorosos (por exemplo, você não deseja instalar o TensorFlow), você poderá instalar um pacote mais fino com DataProfiler[reports] . O pacote mais fino desativa o padrão sensível de detecção / reconhecimento de entidades (Labler)
Instale do Pypi: pip install DataProfiler
No caso desta biblioteca, um perfil de dados é um dicionário que contém estatísticas e previsões sobre o conjunto de dados subjacente. Existem "estatísticas globais" ou global_stats , que contêm dados no nível do conjunto de dados e existem "estatísticas de nível de coluna/linha" ou data_stats (cada coluna é uma nova entrada de valor-chave).
O formato para um perfil estruturado está abaixo:
"global_stats": {
"samples_used": int,
"column_count": int,
"row_count": int,
"row_has_null_ratio": float,
"row_is_null_ratio": float,
"unique_row_ratio": float,
"duplicate_row_count": int,
"file_type": string,
"encoding": string,
"correlation_matrix": list[list[int]], (*)
"chi2_matrix": list[list[float]],
"profile_schema": {
string: list[int]
},
"times": dict[string, float],
},
"data_stats": [
{
"column_name": string,
"data_type": string,
"data_label": string,
"categorical": bool,
"order": string,
"samples": list[str],
"statistics": {
"sample_size": int,
"null_count": int,
"null_types": list[string],
"null_types_index": {
string: list[int]
},
"data_type_representation": dict[string, float],
"min": [null, float, str],
"max": [null, float, str],
"mode": float,
"median": float,
"median_absolute_deviation": float,
"sum": float,
"mean": float,
"variance": float,
"stddev": float,
"skewness": float,
"kurtosis": float,
"num_zeros": int,
"num_negatives": int,
"histogram": {
"bin_counts": list[int],
"bin_edges": list[float],
},
"quantiles": {
int: float
},
"vocab": list[char],
"avg_predictions": dict[string, float],
"data_label_representation": dict[string, float],
"categories": list[str],
"unique_count": int,
"unique_ratio": float,
"categorical_count": dict[string, int],
"gini_impurity": float,
"unalikeability": float,
"precision": {
'min': int,
'max': int,
'mean': float,
'var': float,
'std': float,
'sample_size': int,
'margin_of_error': float,
'confidence_level': float
},
"times": dict[string, float],
"format": string
},
"null_replication_metrics": {
"class_prior": list[int],
"class_sum": list[list[int]],
"class_mean": list[list[int]]
}
}
]
(*) Atualmente, a atualização da matriz de correlação é eliminada. Ele será redefinido em uma atualização posterior. Os usuários ainda podem usá -lo conforme desejado com a opção IS_ENABLE definida como true.
O formato para um perfil não estruturado está abaixo:
"global_stats": {
"samples_used": int,
"empty_line_count": int,
"file_type": string,
"encoding": string,
"memory_size": float, # in MB
"times": dict[string, float],
},
"data_stats": {
"data_label": {
"entity_counts": {
"word_level": dict[string, int],
"true_char_level": dict[string, int],
"postprocess_char_level": dict[string, int]
},
"entity_percentages": {
"word_level": dict[string, float],
"true_char_level": dict[string, float],
"postprocess_char_level": dict[string, float]
},
"times": dict[string, float]
},
"statistics": {
"vocab": list[char],
"vocab_count": dict[string, int],
"words": list[string],
"word_count": dict[string, int],
"times": dict[string, float]
}
}
O formato para um perfil de gráfico está abaixo:
"num_nodes": int,
"num_edges": int,
"categorical_attributes": list[string],
"continuous_attributes": list[string],
"avg_node_degree": float,
"global_max_component_size": int,
"continuous_distribution": {
"<attribute_1>": {
"name": string,
"scale": float,
"properties": list[float, np.array]
},
"<attribute_2>": None,
...
},
"categorical_distribution": {
"<attribute_1>": None,
"<attribute_2>": {
"bin_counts": list[int],
"bin_edges": list[float]
},
...
},
"times": dict[string, float]
samples_used - Número de amostras de dados de entrada usadas para gerar este perfilcolumn_count - O número de colunas contidas no conjunto de dados de entradarow_count - o número de linhas contidas no conjunto de dados de entradarow_has_null_ratio - a proporção de linhas que contêm pelo menos um valor nulo para o número total de linhasrow_is_null_ratio - a proporção de linhas que são totalmente compostas por valores nulos (linhas nulas) para o número total de linhasunique_row_ratio - a proporção de linhas distintas no conjunto de dados de entrada para o número total de linhasduplicate_row_count - o número de linhas que ocorrem mais de uma vez no conjunto de dados de entradafile_type - o formato do arquivo que contém o conjunto de dados de entrada (ex: .csv)encoding - A codificação do arquivo que contém o conjunto de dados de entrada (ex: UTF -8)correlation_matrix - Matriz de Shape column_count x column_count contendo os coeficientes de correlação entre cada coluna no conjunto de dadoschi2_matrix - MATRIXA DE SHEPE column_count X column_count contendo as estatísticas do qui -quadrado entre cada coluna no conjunto de dadosprofile_schema - uma descrição do formato da rotulagem do conjunto de dados de entrada cada coluna e seu índice no conjunto de dadosstring - O rótulo da coluna em questão e seu índice no esquema de perfiltimes - a duração do tempo que levou para gerar as estatísticas globais para este conjunto de dados em milissegundos column_name - o rótulo/título desta coluna no conjunto de dados de entradadata_type - o tipo de dados do Python primitivo que está contido nesta colunadata_label - o rótulo/entidade dos dados nesta coluna, conforme determinado pelo componente da gravadoracategorical - 'True' se esta coluna contiver dados categóricosorder - a maneira pela qual os dados nesta coluna são ordenados, se houver, caso contrário, “aleatório”samples - Um pequeno subconjunto de entradas de dados desta colunastatistics - Informações estatísticas sobre a colunasample_size - Número de amostras de dados de entrada usadas para gerar este perfilnull_count - o número de entradas nulas na amostranull_types - Uma lista dos diferentes tipos nulos presentes nesta amostranull_types_index - um ditado contendo cada tipo nulo e uma lista respectiva dos indicios de que está presente nessa amostradata_type_representation - a porcentagem de amostras usadas identificando como cada data_typemin - valor mínimo na amostramax - valor máximo na amostramode - modo das entradas na amostramedian - mediana das entradas na amostramedian_absolute_deviation - o desvio absoluto mediano das entradas na amostrasum - o total de todos os valores amostrados da colunamean - a média de todas as entradas na amostravariance - a variação de todas as entradas na amostrastddev - o desvio padrão de todas as entradas na amostraskewness - a assimetria estatística de todas as entradas na amostrakurtosis - a curtose estatística de todas as entradas na amostranum_zeros - o número de entradas nesta amostra que têm o valor 0num_negatives - O número de entradas nesta amostra que tem um valor menor que 0histogram - contém informações relevantes para o histogramabin_counts - o número de entradas em cada compartimentobin_edges - os limiares de cada compartimentoquantiles - o valor em cada percentil na ordem em que estão listados com base nas entradas na amostravocab - uma lista dos personagens usados nas entradas nesta amostraavg_predictions - Média das confidências de previsão do rótulo de dados em todos os pontos de dados amostradoscategories - Uma lista de cada categoria distinta dentro da amostra se categorial = 'true'unique_count - o número de entradas distintas na amostraunique_ratio - a proporção do número de entradas distintas na amostra para o número total de entradas na amostracategorical_count - Número de entradas amostradas para cada categoria se categorical = 'true'gini_impurity - Medida de com que frequência um elemento escolhido aleatoriamente do conjunto seria rotulado incorretamente se fosse rotulado aleatoriamente de acordo com a distribuição de rótulos no subconjuntounalikeability - um valor que denota com que frequência as entradas diferem uma da outra dentro da amostraprecision - um ditado de estatísticas em relação ao número de dígitos em um número para cada amostratimes - a duração do tempo que levou para gerar as estatísticas desta amostra em milissegundosformat - Lista de possíveis formatos de datetimenull_replication_metrics - Estatísticas de dados particionados com base no valor da coluna é nulo (índice 1 das listas referenciadas por chaves dicadas) ou não (índice 0)class_prior - uma lista que contém probabilidade de um valor de coluna sendo nulo e não nuloclass_sum - uma lista contendo soma de todas as outras linhas com base no valor da coluna é nulo ou nãoclass_mean - uma lista contendo média de todas as outras linhas com base no valor da coluna é nulo ou nãosamples_used - Número de amostras de dados de entrada usadas para gerar este perfilempty_line_count - O número de linhas vazias nos dados de entradafile_type - o tipo de arquivo dos dados de entrada (ex: .txt)encoding - Codificação do arquivo do arquivo de dados de entrada (ex: UTF -8)memory_size - Tamanho dos dados de entrada em MBtimes - Duração do tempo necessário para gerar esse perfil em milissegundos data_label - rótulos e estatísticas nos rótulos dos dados de entradaentity_counts - O número de vezes que uma etiqueta ou entidade específica aparece dentro dos dados de entradaword_level - o número de palavras contadas dentro de cada rótulo ou entidadetrue_char_level - o número de caracteres contados em cada rótulo ou entidade, conforme determinado pelo modelopostprocess_char_level - o número de caracteres contados em cada rótulo ou entidade, conforme determinado pelo pós -processadorentity_percentages - As porcentagens de cada rótulo ou entidade dentro dos dados de entradaword_level - a porcentagem de palavras nos dados de entrada que estão contidos em cada rótulo ou entidadetrue_char_level - a porcentagem de caracteres nos dados de entrada que estão contidos em cada rótulo ou entidade, conforme determinado pelo modelopostprocess_char_level - A porcentagem de caracteres nos dados de entrada que estão contidos em cada rótulo ou entidade, conforme determinado pelo pós -processadortimes - a duração do tempo que levou para o gravador de dados prever os dadosstatistics - Estatísticas dos dados de entradavocab - uma lista de cada caractere nos dados de entradavocab_count - o número de ocorrências de cada caractere distinto nos dados de entradawords - Uma lista de cada palavra nos dados de entradaword_count - O número de ocorrências de cada palavra distinta nos dados de entradatimes - a duração do tempo que levou para gerar as estatísticas de vocabulário e palavras em milissegundosnum_nodes - Número de nós no gráficonum_edges - Número de arestas no gráficocategorical_attributes - Lista de atributos de borda categóricacontinuous_attributes - Lista de atributos de borda contínuaavg_node_degree - grau médio de nós no gráficoglobal_max_component_size : tamanho do componente máximo global <attribute_N> : Nome do atributo n-th Edge na lista de atributosname - Nome da distribuição para atributoscale - probabilidade de log negativa usada para dimensionar e comparar distribuiçõesproperties - Lista de propriedades estatísticas que descrevem a distribuição <attribute_N> : Nome do atributo n-th Edge na lista de atributos
bin_counts : contagens em cada compartimento do histograma de distribuiçãobin_edges : bordas de cada compartimento do histograma de distribuiçãoTempos - Duração do tempo necessário para gerar esse perfil em milissegundos
Os tipos de dados são determinados no nível da coluna para dados estruturados
Os rótulos de dados são determinados por célula para dados estruturados (coluna/linha quando o Profiler é usado) ou no nível do caractere para dados não estruturados.
O Profiler de dados pode perfilar os seguintes tipos de dados/arquivos:
O Profiler deve identificar automaticamente o tipo de arquivo e carregar os dados em uma Data Class .
Juntamente com outros atributas, a Data class permite que os dados sejam acessados por meio de um quadro de dados válidos de pandas.
# Load a csv file, return a CSVData object
csv_data = Data ( 'your_file.csv' )
# Print the first 10 rows of the csv file
print ( csv_data . data . head ( 10 ))
# Load a parquet file, return a ParquetData object
parquet_data = Data ( 'your_file.parquet' )
# Sort the data by the name column
parquet_data . data . sort_values ( by = 'name' , inplace = True )
# Print the sorted first 10 rows of the parquet data
print ( parquet_data . data . head ( 10 ))
# Load a json file from a URL, return a JSONData object
json_data = Data ( 'https://github.com/capitalone/DataProfiler/blob/main/dataprofiler/tests/data/json/iris-utf-8.json' )Se o tipo de arquivo não for identificado automaticamente (raro), você poderá especificá -los especificamente, consulte a seção Especificando um FileType ou Delimiter.
O exemplo usa um arquivo CSV, por exemplo, mas CSV, JSON, AVRO, Parquet ou texto também funcionam.
import json
from dataprofiler import Data , Profiler
# Load file (CSV should be automatically identified)
data = Data ( "your_file.csv" )
# Profile the dataset
profile = Profiler ( data )
# Generate a report and use json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
# Print the report
print ( json . dumps ( report , indent = 4 ))Atualmente, o Profiler de dados está equipado para atualizar seu perfil em lotes.
import json
from dataprofiler import Data , Profiler
# Load and profile a CSV file
data = Data ( "your_file.csv" )
profile = Profiler ( data )
# Update the profile with new data:
new_data = Data ( "new_data.csv" )
profile . update_profile ( new_data )
# Print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))Observe que, se os dados que você atualizar o perfil contiver índices inteiros que se sobrepõem aos índices nos dados originalmente perfilados, quando as linhas nulas são calculadas, os índices serão "deslocados" para valores desabitados, para que as contagens e os índices nulos ainda sejam precisos.
Se você tiver dois arquivos com o mesmo esquema (mas dados diferentes), é possível mesclar os dois perfis por meio de um operador de adição.
Isso também permite que os perfis sejam determinados de maneira distribuída.
import json
from dataprofiler import Data , Profiler
# Load a CSV file with a schema
data1 = Data ( "file_a.csv" )
profile1 = Profiler ( data1 )
# Load another CSV file with the same schema
data2 = Data ( "file_b.csv" )
profile2 = Profiler ( data2 )
profile3 = profile1 + profile2
# Print the report using json to prettify.
report = profile3 . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))Observe que, se os perfis mesclados tivessem índices inteiros sobrepostos, quando as linhas nulas são calculadas, os índices serão "deslocados" para valores desabitados, para que as contagens e proporções nulas ainda sejam precisas.
Para encontrar a mudança entre os perfis com o mesmo esquema, podemos utilizar a função diff do perfil. O diff fornecerá diferenças gerais de arquivo e amostragem, bem como diferenças detalhadas das estatísticas dos dados. Por exemplo, colunas numéricas têm um teste t para avaliar a similaridade e o PSI (índice de estabilidade populacional) para quantificar a mudança de distribuição de colunas. Mais informações são descritas na seção Profiler das páginas do GitHub.
Crie o relatório de diferença como este:
import json
import dataprofiler as dp
# Load a CSV file
data1 = dp . Data ( "file_a.csv" )
profile1 = dp . Profiler ( data1 )
# Load another CSV file
data2 = dp . Data ( "file_b.csv" )
profile2 = dp . Profiler ( data2 )
diff_report = profile1 . diff ( profile2 )
print ( json . dumps ( diff_report , indent = 4 )) import pandas as pd
import dataprofiler as dp
import json
my_dataframe = pd . DataFrame ([[ 1 , 2.0 ],[ 1 , 2.2 ],[ - 1 , 3 ]])
profile = dp . Profiler ( my_dataframe )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))
# read a specified column, in this case it is labeled 0:
print ( json . dumps ( report [ "data_stats" ][ 0 ], indent = 4 )) Além do Profiler estruturado, o DataProfiler fornece perfil não estruturado para o objeto ou string textdata. O Profiler não estruturado também funciona com a List [String], PD.Series (String) ou PD.Dataframe (String), dada a opção Profiler_type especificada como unstructured . Abaixo está um exemplo do Profiler não estruturado com um arquivo de texto.
import dataprofiler as dp
import json
my_text = dp . Data ( 'text_file.txt' )
profile = dp . Profiler ( my_text )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 )) Outro exemplo do perfilador não estruturado com PD.Series of Strings é dado como abaixo, com a opção Profiler profiler_type='unstructured'
import dataprofiler as dp
import pandas as pd
import json
text_data = pd . Series ([ 'first string' , 'second string' ])
profile = dp . Profiler ( text_data , profiler_type = 'unstructured' )
# print the report using json to prettify.
report = profile . report ( report_options = { "output_format" : "pretty" })
print ( json . dumps ( report , indent = 4 ))O DataProfiler também fornece a capacidade de perfilar dados gráficos de um arquivo CSV. Abaixo está um exemplo do Profiler de gráfico com um arquivo CSV de dados gráficos:
import dataprofiler as dp
import pprint
my_graph = dp . Data ( 'graph_file.csv' )
profile = dp . Profiler ( my_graph )
# print the report using pretty print (json dump does not work on numpy array values inside dict)
report = profile . report ()
printer = pprint . PrettyPrinter ( sort_dicts = False , compact = True )
printer . pprint ( report )Visite a página de documentação para obter exemplos adicionais e detalhes da API
Sensitive Data Detection with High-Throughput Neural Network Models for Financial Institutions
Authors: Anh Truong, Austin Walters, Jeremy Goodsitt
2020 https://arxiv.org/abs/2012.09597
The AAAI-21 Workshop on Knowledge Discovery from Unstructured Data in Financial Services