Je travaille avec spark 2.2.0 et pyspark2.
J'ai créé un DataFrame df
et j'essaye maintenant d'ajouter une nouvelle colonne "rowhash"
Qui est le hachage sha2 de colonnes spécifiques dans le DataFrame.
Par exemple, disons que df
a les colonnes: (column1, column2, ..., column10)
J'ai besoin de sha2((column2||column3||column4||...... column8), 256)
dans une nouvelle colonne "rowhash"
.
Pour l'instant, j'ai essayé d'utiliser les méthodes ci-dessous:
1) Fonction hash()
utilisée mais comme elle donne une sortie entière, elle n'est pas très utile
2) J'ai essayé d'utiliser la fonction sha2()
mais elle échoue.
Disons que columnarray
a un tableau de colonnes dont j'ai besoin.
def concat(columnarray):
concat_str = ''
for val in columnarray:
concat_str = concat_str + '||' + str(val)
concat_str = concat_str[2:]
return concat_str
puis
df1 = df1.withColumn("row_sha2", sha2(concat(columnarray),256))
Cela échoue avec l'erreur "impossible à résoudre".
Merci ma gueule pour ta réponse. Comme je ne dois hacher que des colonnes spécifiques, j'ai créé une liste de ces noms de colonnes (dans hash_col) et changé votre fonction comme:
def sha_concat(row, columnarray):
row_dict = row.asDict() #transform row to a dict
concat_str = ''
for v in columnarray:
concat_str = concat_str + '||' + str(row_dict.get(v))
concat_str = concat_str[2:]
#preserve concatenated value for testing (this can be removed later)
row_dict["sha_values"] = concat_str
row_dict["sha_hash"] = hashlib.sha256(concat_str).hexdigest()
return Row(**row_dict)
Puis passé comme:
df1.rdd.map(lambda row: sha_concat(row,hash_col)).toDF().show(truncate=False)
Il échoue cependant maintenant avec erreur:
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 8: ordinal not in range(128)
Je peux voir la valeur de\ufffd dans l'une des colonnes, donc je ne sais pas s'il existe un moyen de gérer cela?
Si vous voulez avoir le hachage pour chaque valeur dans les différentes colonnes de votre jeu de données, vous pouvez appliquer une fonction conçue par vous-même via map
au rdd de votre dataframe.
import hashlib
test_df = spark.createDataFrame([
(1,"2",5,1),(3,"4",7,8),
], ("col1","col2","col3","col4"))
def sha_concat(row):
row_dict = row.asDict() #transform row to a dict
columnarray = row_dict.keys() #get the column names
concat_str = ''
for v in row_dict.values():
concat_str = concat_str + '||' + str(v) #concatenate values
concat_str = concat_str[2:]
row_dict["sha_values"] = concat_str #preserve concatenated value for testing (this can be removed later)
row_dict["sha_hash"] = hashlib.sha256(concat_str).hexdigest() #calculate sha256
return Row(**row_dict)
test_df.rdd.map(sha_concat).toDF().show(truncate=False)
Les résultats ressembleraient à:
+----+----+----+----+----------------------------------------------------------------+----------+
|col1|col2|col3|col4|sha_hash |sha_values|
+----+----+----+----+----------------------------------------------------------------+----------+
|1 |2 |5 |1 |1b0ae4beb8ce031cf585e9bb79df7d32c3b93c8c73c27d8f2c2ddc2de9c8edcd|1||2||5||1|
|3 |4 |7 |8 |cb8f8c5d9fd7165cf3c0f019e0fb10fa0e8f147960c715b7f6a60e149d3923a5|8||4||7||3|
+----+----+----+----+----------------------------------------------------------------+----------+