首页 > 解决方案 > 大型数组中元素的字符串比较(> 11 mill)

问题描述

试图比较 id(字符串)上的不同环境。最大的阵列是 11,5 磨行。

我想要做的是组合来自不同数组的所有 id,然后告诉每个 id 所在的环境

我正在尝试创建的内容:

id(所有数组的所有id(df) 产品 预制品 测试 开发者
第一个字符串 真的 真的 真的 错误的
第二个字符串 错误的 真的 错误的 真的
21gdfwg23fge 真的 真的 错误的 错误的
adf23 dfg a2-5 真的 错误的 真的 真的
示例 1
%%time
dfs = [prod,preprod,test,dev]
arrs = [np.array(df).flatten() for df in dfs]
all_ids = np.unique([item for sublist in arrs for item in sublist])
n_ids = len(all_ids)
n_arrs = len(arrs)
result = np.zeros((n_ids, n_arrs))
for i in range(n_arrs):
    result[:, i] = [1 if all_ids[j] in arrs[i] else 0 for j in range(n_ids)]
result_df = pd.DataFrame(result, columns=['dev', 'test', 'preprod', 'prod'], index = all_ids)
print(result_df)

示例 2:(更易于阅读)

final = pd.concat([prod, preprod, dev, test]).drop_duplicates()
final = final.dropna()

all = final

prod_num = prod.to_numpy()
preprod_num = prod.to_numpy()
dev_num = dev.to_numpy()
test_num = test.to_numpy()

prod_isin = np.isin(all,prod_num)
preprod_isin = np.isin(all,preprod_num)
dev_isin = np.isin(all, dev_num)
test_isin = np.isin(all, test_num)

final["prod"] = prod_isin
final["preprod"] = preprod_isin
final["dev"] = dev_isin
final["test"] = test_isin
print(final)

代码有效,但速度太慢了

我也试过 GPU(没有让它工作(有一个 Nvidia 1080 TI))。想想我应该做的是对“主”列表进行排序,然后使用某种排序算法进行匹配。

所有帮助都将得到应用

标签: pythonpandasnumpygpustring-comparison

解决方案


您可以将 pandas 连接与索引匹配一起使用,它非常快。

prod = "aa|b|c|d|e".split('|')
preprod = "c|d|e".split('|')
test = "b|d|e|f".split('|')
dev = "aa|e|g".split('|')

df = pd.concat([
    pd.DataFrame({'prod': 1}, index=np.unique(prod)),
    pd.DataFrame({'preprod': 1}, index=np.unique(preprod)),
    pd.DataFrame({'test': 1}, index=np.unique(test)),
    pd.DataFrame({'dev': 1}, index=np.unique(dev))
], axis=1, sort=False).fillna(0).reset_index().rename(columns={'index': 'id'})
print(df)

>>> 
   id  prod  preprod  test  dev
0  aa   1.0      0.0   0.0  1.0
1   b   1.0      0.0   1.0  0.0
2   c   1.0      1.0   0.0  0.0
3   d   1.0      1.0   1.0  0.0
4   e   1.0      1.0   1.0  1.0
5   f   0.0      0.0   1.0  0.0
6   g   0.0      0.0   0.0  1.0

和速度;

prod = np.random.randint(10000000, size=10000000).astype(str)
preprod = np.random.randint(10000000, size=1000000).astype(str)
test = np.random.randint(10000000, size=1000000).astype(str)
dev = np.random.randint(10000000, size=100000).astype(str)


%%time
df = pd.concat([
    pd.DataFrame({'prod': 1}, index=np.unique(prod)),
    pd.DataFrame({'preprod': 1}, index=np.unique(preprod)),
    pd.DataFrame({'test': 1}, index=np.unique(test)),
    pd.DataFrame({'dev': 1}, index=np.unique(dev))
], axis=1, sort=False).fillna(0).reset_index().rename(columns={'index': 'id'})

>>> Wall time: 32.3 s

在我不起眼的笔记本电脑上。


推荐阅读