我已经加载了一个带有 json 文件的 s3 存储桶,并将其解析/展平到 pandas 数据帧中。现在我有一个包含 175 列的数据框,其中 4 列包含个人身份信息。
我正在寻找一种对这些列(名称和地址)进行匿名化的快速解决方案。我需要保留多个信息,以便同一个人的姓名或地址多次出现时具有相同的哈希值。
pandas 或其他一些我可以利用的包中是否有现有功能?
使用 aCategorical
将是一种有效的方法 - 主要警告是编号将仅基于数据中的顺序,因此如果需要跨多个列/数据集使用此编号方案,则需要小心。
df = pd.DataFrame({'ssn': [1, 2, 3, 999, 10, 1]})
df['ssn_anon'] = df['ssn'].astype('category').cat.codes
df
Out[38]:
ssn ssn_anon
0 1 0
1 2 1
2 3 2
3 999 4
4 10 3
5 1 0
您可以使用ngroup
或factorize
从pandas
df.groupby('ssn').ngroup()
Out[25]:
0 0
1 1
2 2
3 4
4 3
5 0
dtype: int64
pd.factorize(df.ssn)[0]
Out[26]: array([0, 1, 2, 3, 4, 0], dtype=int64)
在 sklearn 中,如果你在做 ML,我会推荐这种方法
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(df.ssn).transform(df.ssn)
Out[31]: array([0, 1, 2, 4, 3, 0], dtype=int64)
您似乎正在寻找一种方法来加密数据框中的字符串。有一堆python加密库,比如cryptography
如何使用它非常简单,只需将其应用于每个元素。
import pandas as pd
from cryptography.fernet import Fernet
df =pd.DataFrame([{'a':'a','b':'b'}, {'a':'a','b':'c'}])
f = Fernet('password')
res = df.applymap(lambda x: f.encrypt(byte(x, 'utf-8'))
# Decrypt
res.applymap(lambda x: f.decrypt(x))
就安全性而言,这可能是最好的方法,但它会生成一个长字节/字符串并且很难查看。
# 'a' -> b'gAAAAABaRQZYMjB7wh-_kD-VmFKn2zXajMRUWSAeridW3GJrwyebcDSpqyFGJsCEcRcf68ylQMC83G7dyqoHKUHtjskEtne8Fw=='
解决问题的另一种简单方法是创建一个函数,将键映射到值并在存在新键时创建新值。
mapper = {}
def encode(string):
if x not in mapper:
# This part can be changed with anything really
# Such as mapper[x]=randint(-10**10,10**10)
# Just ensure it would not repeat
mapper[x] = len(mapper)+1
return mapper[x]
res = df.applymap(encode)
听起来有点像您希望能够通过在某处维护密钥来逆转该过程。如果您的用例允许,我建议将所有值替换为有效、人类可读且不可逆的占位符。
约翰 > 马克
21 Hammersmith Grove rd > 48 Brewer Street
这有利于为远程开发人员生成可用的测试数据等。您可以使用Faker自己生成替换值。如果您想在数据中维护一些实用程序,即“将所有地址替换为 2 英里内的备用地址”,您可以使用我正在开发的名为Anon AI的 api 。我们从 s3 存储桶中解析 JSON,自动查找所有 PII(包括在自由文本字段中),并根据您的规范将其替换为占位符。如果需要,我们可以保持一致性和可逆性,如果您想保持不断增长的数据集的“实时”匿名版本,这将是最有用的。我们目前处于测试阶段,因此请告诉我您是否有兴趣对其进行测试。