【发布时间】:2021-07-31 11:57:44
【问题描述】:
我有一个非常大的熊猫数据框格式的知识图,如下所示。
这个数据框 KG 有超过 1 亿行:
pred subj obj
0 nationality BART USA
1 placeOfBirth BART NEWYORK
2 locatedIn NEWYORK USA
... ... ... ...
116390740 hasFather BART HOMMER
116390741 nationality HOMMER USA
116390743 placeOfBirth HOMMER NEWYORK
我试图从这个KG 中获取一个具有特定值的 subj 和 obj 的行。
a) 我尝试通过使用isin() 函数生成布尔系列来索引KG:
KG[KG['subj'].isin(['BART', 'NEWYORK']) & KG['obj'].isin(['USA', 'HOMMER'])]
b) 我还尝试使用query() 函数对KG 进行索引:
KG = KG.set_index(['subj','obj'], drop=True)
KG = KG.sort_index()
subj_substitution = ['BART', 'NEWYORK']
obj_substitution= ['USA', 'HOMMER']
KG.query(f"subj in {subj_substitution} & obj in {obj_substitution}
c) 我还尝试使用merge() 加入两个 DataFrame,如下所示。
subj_df
subj
0 BART
1 NEWYORK
obj_df
obj
0 USA
1 HOMMER
merge_result = pd.merge(KG, subj_df, on = ['subj']).drop_duplicates()
merge_result = pd.merge(merge_result, obj_df, on = ['obj']).drop_duplicates()
这些方法的结果如下:
pred subj obj
0 nationality BART USA
2 locatedIn NEWYORK USA
116390740 hasFather BART HOMMER
我使用timeit 函数来检查每个时间,如下所示。
timeit.timeit(lambda: KG[(KG['subj'].isin(['BART', 'NEWYORK']) & (KG['obj'].isin(['USA', 'HOMMER'])))] , number=10)
运行时是:
| function | runtime |
|---|---|
isin() |
35.6s |
query() |
155.2s |
merge() |
288.9s |
我认为isin() 是索引一个非常大的数据框的最快方法。
如果您能告诉我比这更快的方法,我将不胜感激。
【问题讨论】:
-
pred,subj,obj都是低基数的字符串。将它们转换为pd.Categorical,然后它们将在引擎盖下被表示为整数。如果您可以将 1K 行数据集作为附件发布,我将发布代码。 -
其实只是告诉我们每列的基数:
KG.apply(pd.Series.nunique, axis=0) -
Won chul Shin:但这只是前 6 行多次复制。它不会行使基数(少数唯一值)。
-
对不起,我会给你一些新数据,所以你可以试试这个。谢谢您的帮助。 drive.google.com/file/d/1rNjvvUJxM4LCn9qnWdyOhlWtwK--A577/…
-
您能否告诉我们每列的基数,如问:
KG.apply(pd.Series.nunique, axis=0)?
标签: python pandas performance indexing