<jupyter_start><jupyter_text>Set operations on RDDs  [Baseado em "Introduction to Spark with Python, by <NAME>"](https://github.com/jadianes/spark-py-notebooks) O Spark suporta muitas das operações que temos em conjuntos matemáticos, como união e interseção, mesmo quando os próprios RDDs não estão configurados corretamente. É importante observar que essas operações exigem que os RDDs que estão sendo operados sejam do mesmo tipo. Definir operações é bastante simples de entender como funciona conforme o esperado. A única consideração vem do fato de que os RDDs não são conjuntos reais e, portanto, operações como a união de RDDs não removem duplicatas. Neste notebook, vamos dar uma breve olhada em `subtract`, `distinct` e `cartesian`.  Obtendo os dados e criando o RDD Como fizemos em nosso primeiro notebook, usaremos o conjunto de dados reduzido 10% do fornecido para a KDD Cup 1999, contendo quase meio milhão de interações de rede. O arquivo é fornecido como um arquivo Gzip que será baixado localmente.<jupyter_code>from urllib.request import urlretrieve

f = urlretrieve("http://kdd.ics.uci.edu/databases/kddcup99/kddcup.data_10_percent.gz", "kddcup.data_10_percent.gz")
data_file = "./kddcup.data_10_percent.gz"
raw_data = sc.textFile(data_file)<jupyter_output><empty_output><jupyter_text>Obtendo interações de ataque usando `subtract` Para fins ilustrativos, imagine que já temos nosso RDD com interações de não ataque (normal) de alguma análise anterior.<jupyter_code>normal_raw_data = raw_data.filter(lambda x: "normal." in x)<jupyter_output><empty_output><jupyter_text>Podemos obter interações de ataque subtraindo as normais do RDD não filtrado original da seguinte maneira.<jupyter_code>attack_raw_data = raw_data.subtract(normal_raw_data)<jupyter_output><empty_output><jupyter_text>Vamos fazer algumas contagens para verificar nossos resultados.<jupyter_code>from time import time

# count all
t0 = time()
raw_data_count = raw_data.count()
tt = time() - t0
print("All count in {} secs".format(round(tt,3)))
# count normal
t0 = time()
normal_raw_data_count = normal_raw_data.count()
tt = time() - t0
print("Normal count in {} secs".format(round(tt,3)))
# count attacks
t0 = time()
attack_raw_data_count = attack_raw_data.count()
tt = time() - t0
print("Attack count in {} secs".format(round(tt,3)))
print("There are {} normal interactions and {} attacks, \
from a total of {} interactions".format(normal_raw_data_count,attack_raw_data_count,raw_data_count))<jupyter_output>There are 97278 normal interactions and 396743 attacks, from a total of 494021 interactions<jupyter_text>Então agora temos dois RDDs, um com interações normais e outro com ataques.  Combinações de protocolos e serviços usando `cartesian` Podemos calcular o produto cartesiano entre dois RDDs usando a transformação cartesiana. Ele retorna todos os possíveis pares de elementos entre dois RDDs. Em nosso caso, vamos usá-lo para gerar todas as combinações possíveis entre serviço e protocolo em nossas interações de rede.Primeiro de tudo, precisamos isolar cada coleção de valores em dois RDDs separados. Para isso, usaremos `distinct` no conjunto de dados analisado por CSV. A partir da [descrição do conjunto de dados](http://kdd.ics.uci.edu/databases/kddcup99/kddcup.names) sabemos que o protocolo é a segunda coluna e o serviço é o terceiro (a tag é a última e não a primeira como aparece na página). Então, primeiro, vamos pegar os protocolos.<jupyter_code>csv_data = raw_data.map(lambda x: x.split(","))
protocols = csv_data.map(lambda x: x[1]).distinct()
protocols.collect()<jupyter_output><empty_output><jupyter_text>Agora fazemos o mesmo pelos serviços.<jupyter_code>services = csv_data.map(lambda x: x[2]).distinct()
services.collect()<jupyter_output><empty_output><jupyter_text>Uma lista mais longa neste caso. Agora podemos fazer o produto cartesiano.<jupyter_code>product = protocols.cartesian(services).collect()
print("There are {} combinations of protocol X service".format(len(product)))<jupyter_output>There are 198 combinations of protocol X service
{'fraction_non_alphanumeric': 0.0810744208969936, 'fraction_numerical': 0.011582060128141941, 'mean_word_length': 6.171378091872792, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '295639', 'license': 'MIT', 'n_tokens_mistral': 1409, 'n_tokens_neox': 1352, 'n_words': 448, 'path': 'nb4-rdd-set/nb4-rdd-set.ipynb', 'repo_name': 'v4ires/caipyra-2018-pyspark', 'size': '4066'}