我已经加载了一个带有json文件的s3存储桶,并将其解析/展平为一个pandas数据帧。现在我有一个包含175列的数据框,其中4列包含个人身份信息。
我正在寻找一个快速解决方案匿名这些列(名称和地址)。我需要保留倍数的信息,以便如果多次出现的同一个人的姓名或地址具有相同的哈希值。
在熊猫或其他一些我可以使用的软件包中是否有现有的功能?
使用Categorical
将是一种有效的方法 - 主要的警告是编号将仅基于数据中的排序,因此如果需要跨多个列/数据集使用此编号方案,则需要一些小心。
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(包括在自由文本字段中),并根据您的规范将其替换为占位符。如果需要,我们可以保持一致性和可逆性,如果您想保留不断增长的数据集的“实时”匿名版本,它将是最有用的。我们目前处于测试阶段,如果您有兴趣测试一下,请告诉我。