pandas 中的向量化哈希函数
Vectorizing hashing function in pandas
我有以下数据集(具有不同的值,只是将相同的行相乘)。
我需要合并列并对它们进行哈希处理,特别是使用库 hashlib 和提供的算法。
问题是它花费的时间太长了,不知怎的,我觉得我可以向量化这个函数,但我不是专家。
功能很简单,感觉可以向量化,但是实现起来比较吃力。
我正在处理数百万行,这需要几个小时,即使对 4 列值进行哈希处理也是如此。
import pandas as pd
import hashlib
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* 100000,'second_identifier':['RED413','BLU031']* 100000})
def _mutate_hash(row):
return hashlib.md5(row.sum().lower().encode()).hexdigest()
%timeit data['row_hash']=data.apply(_mutate_hash,axis=1)
使用列表推导式可以显着加快速度。
首先是你的原创:
import pandas as pd
import hashlib
n = 100000
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* n,'second_identifier':['RED413','BLU031']* n})
def _mutate_hash(row):
return hashlib.md5(row.sum().lower().encode()).hexdigest()
%timeit data['row_hash']=data.apply(_mutate_hash,axis=1)
1 loop, best of 5: 26.1 s per loop
然后作为列表理解:
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* n,'second_identifier':['RED413','BLU031']* n})
def list_comp(df):
return pd.Series([ _mutate_hash(row) for row in df.to_numpy() ])
%timeit data['row_hash']=list_comp(data)
1 loop, best of 5: 872 ms per loop
...即加速约 30 倍。
作为检查:您可以检查这两种方法是否产生相同的结果,方法是将第一个放在“data2”中,将第二个放在“data3”中,然后检查他们是平等的:
data2, data3 = pd.DataFrame([]), pd.DataFrame([])
%timeit data2['row_hash']=data.apply(_mutate_hash,axis=1)
...
%timeit data3['row_hash']=list_comp(data)
...
data2.equals(data3)
True
最简单的性能提升来自使用矢量化字符串操作。如果您在应用哈希函数之前进行字符串准备(小写和编码),您的性能会更合理。
data = pd.DataFrame(
{
"first_identifier": ["ALP1x", "RDX2b"] * 1000000,
"second_identifier": ["RED413", "BLU031"] * 1000000,
}
)
def _mutate_hash(row):
return hashlib.md5(row).hexdigest()
prepped_data = data.apply(lambda col: col.str.lower().str.encode("utf8")).sum(axis=1)
data["row_hash"] = prepped_data.map(_mutate_hash)
我看到该更改的速度提高了约 25 倍。
我有以下数据集(具有不同的值,只是将相同的行相乘)。 我需要合并列并对它们进行哈希处理,特别是使用库 hashlib 和提供的算法。
问题是它花费的时间太长了,不知怎的,我觉得我可以向量化这个函数,但我不是专家。
功能很简单,感觉可以向量化,但是实现起来比较吃力。
我正在处理数百万行,这需要几个小时,即使对 4 列值进行哈希处理也是如此。
import pandas as pd
import hashlib
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* 100000,'second_identifier':['RED413','BLU031']* 100000})
def _mutate_hash(row):
return hashlib.md5(row.sum().lower().encode()).hexdigest()
%timeit data['row_hash']=data.apply(_mutate_hash,axis=1)
使用列表推导式可以显着加快速度。
首先是你的原创:
import pandas as pd
import hashlib
n = 100000
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* n,'second_identifier':['RED413','BLU031']* n})
def _mutate_hash(row):
return hashlib.md5(row.sum().lower().encode()).hexdigest()
%timeit data['row_hash']=data.apply(_mutate_hash,axis=1)
1 loop, best of 5: 26.1 s per loop
然后作为列表理解:
data = pd.DataFrame({'first_identifier':['ALP1x','RDX2b']* n,'second_identifier':['RED413','BLU031']* n})
def list_comp(df):
return pd.Series([ _mutate_hash(row) for row in df.to_numpy() ])
%timeit data['row_hash']=list_comp(data)
1 loop, best of 5: 872 ms per loop
...即加速约 30 倍。
作为检查:您可以检查这两种方法是否产生相同的结果,方法是将第一个放在“data2”中,将第二个放在“data3”中,然后检查他们是平等的:
data2, data3 = pd.DataFrame([]), pd.DataFrame([])
%timeit data2['row_hash']=data.apply(_mutate_hash,axis=1)
...
%timeit data3['row_hash']=list_comp(data)
...
data2.equals(data3)
True
最简单的性能提升来自使用矢量化字符串操作。如果您在应用哈希函数之前进行字符串准备(小写和编码),您的性能会更合理。
data = pd.DataFrame(
{
"first_identifier": ["ALP1x", "RDX2b"] * 1000000,
"second_identifier": ["RED413", "BLU031"] * 1000000,
}
)
def _mutate_hash(row):
return hashlib.md5(row).hexdigest()
prepped_data = data.apply(lambda col: col.str.lower().str.encode("utf8")).sum(axis=1)
data["row_hash"] = prepped_data.map(_mutate_hash)
我看到该更改的速度提高了约 25 倍。