to_dict 的奇怪行为
Odd behavior of to_dict
我正在构建一个模糊搜索程序,使用 FuzzyWuzzy 在数据集中查找匹配的名称。正如预期的那样,我的数据位于大约 10378 行的 DataFrame 中,len(df['Full name'])
是 10378。但是len(choices)
只有1695.
我是 运行 Python 2.7.10
和 pandas 0.17.0
,在 IPython 笔记本中。
choices = df['Full name'].astype(str).to_dict()
def fuzzy_search_to_df (term, choices=choices):
search = process.extract(term, choices, limit=len(choices)) # does the search itself
rslts = pd.DataFrame(data=search, index=None, columns=['name', 'rel', 'df_ind']) # puts the results in DataFrame form
return rslts
results = fuzzy_search_to_df(term='Ben Franklin') # returns the search result for the given term
matches = results[results.rel > 85] # subset of results, these are the best search results
find = df.iloc[matches['df_ind']] # matches in the main df
你可能会说,我在 choices
字典中得到的结果索引为 df_ind
,我原以为它与主数据框中的索引相同.
我相当确定问题出在第一行,使用 to_dict()
函数,因为 len(df['Full name'].astype(str)
结果为 10378,而 len(df['Full name'].to_dict())
结果为 1695。
问题是您的数据框中有多行,其中的索引相同,因此由于 Python 字典只能保存单个键的单个值,而在 Series.to_dict()
方法,索引用作键,这些行中的值将被后面的值覆盖。
展示此行为的一个非常简单的示例 -
In [36]: df = pd.DataFrame([[1],[2]],index=[1,1],columns=['A'])
In [37]: df
Out[37]:
A
1 1
1 2
In [38]: df['A'].to_dict()
Out[38]: {1: 2}
这就是您的情况,并从评论中注意到,由于索引的 unique
值的数量仅为 1695
,我们可以通过测试的值来确认这一点len(df.index.unique())
.
如果您满足于将数字作为 key
(数据帧的索引),那么您可以使用 DataFrame.reset_index()
重置索引,然后在其上使用 .to_dict()
。示例 -
choices = df.reset_index()['Full name'].astype(str).to_dict()
上面示例的演示 -
In [40]: df.reset_index()['A'].to_dict()
Out[40]: {0: 1, 1: 2}
这与 OP 找到的解决方案相同 - choices = dict(zip(df['n'],df['Full name'].astype(str)))
(从评论中可以看出) - 但这种方法比使用 zip
和 dict
更快。
我正在构建一个模糊搜索程序,使用 FuzzyWuzzy 在数据集中查找匹配的名称。正如预期的那样,我的数据位于大约 10378 行的 DataFrame 中,len(df['Full name'])
是 10378。但是len(choices)
只有1695.
我是 运行 Python 2.7.10
和 pandas 0.17.0
,在 IPython 笔记本中。
choices = df['Full name'].astype(str).to_dict()
def fuzzy_search_to_df (term, choices=choices):
search = process.extract(term, choices, limit=len(choices)) # does the search itself
rslts = pd.DataFrame(data=search, index=None, columns=['name', 'rel', 'df_ind']) # puts the results in DataFrame form
return rslts
results = fuzzy_search_to_df(term='Ben Franklin') # returns the search result for the given term
matches = results[results.rel > 85] # subset of results, these are the best search results
find = df.iloc[matches['df_ind']] # matches in the main df
你可能会说,我在 choices
字典中得到的结果索引为 df_ind
,我原以为它与主数据框中的索引相同.
我相当确定问题出在第一行,使用 to_dict()
函数,因为 len(df['Full name'].astype(str)
结果为 10378,而 len(df['Full name'].to_dict())
结果为 1695。
问题是您的数据框中有多行,其中的索引相同,因此由于 Python 字典只能保存单个键的单个值,而在 Series.to_dict()
方法,索引用作键,这些行中的值将被后面的值覆盖。
展示此行为的一个非常简单的示例 -
In [36]: df = pd.DataFrame([[1],[2]],index=[1,1],columns=['A'])
In [37]: df
Out[37]:
A
1 1
1 2
In [38]: df['A'].to_dict()
Out[38]: {1: 2}
这就是您的情况,并从评论中注意到,由于索引的 unique
值的数量仅为 1695
,我们可以通过测试的值来确认这一点len(df.index.unique())
.
如果您满足于将数字作为 key
(数据帧的索引),那么您可以使用 DataFrame.reset_index()
重置索引,然后在其上使用 .to_dict()
。示例 -
choices = df.reset_index()['Full name'].astype(str).to_dict()
上面示例的演示 -
In [40]: df.reset_index()['A'].to_dict()
Out[40]: {0: 1, 1: 2}
这与 OP 找到的解决方案相同 - choices = dict(zip(df['n'],df['Full name'].astype(str)))
(从评论中可以看出) - 但这种方法比使用 zip
和 dict
更快。