【问题标题】:Python: TypeError: unhashable type: 'list' when MongoDB queryPython:TypeError:不可散列的类型:MongoDB查询时的'list'
【发布时间】:2018-10-15 09:01:55
【问题描述】:

为了让大家更容易理解我的问题,我会先总结一下。

“今天我只查询了一个我以前从未访问过的平面文件,但相同的代码适用于同一个 MongoDB 集合上的其他平面文件。”

详情如下,

我有一个列表要查询customer_id,我的列表叫alist

[7068, 7116, 7154, 7342, 7379]

我在 python 上使用 pandaspymongo 进行 MongoDB 查询。这是我的 MongoDB 查询,这是我导入的库

import pandas as pd
from pymongo import MongoClient
import datetime as dt

之后,我提供数据库凭据。这是凭证

mongo_client = MongoClient(host= ... ,port= ... ,username= ...,password= ... ,authSource='admin')
db = mongo_client['something-info']
cv = db['flat_something']

这是查询

data = cv.find()
query_filter_alist = {'customer_id': {'$in': alist}}
query_project = {'_id':0}
cursor_list = cv.find(query_filter_alist, query_project)
contacts = pd.DataFrame(list(cursor_list)).drop_duplicates()

它适用于同一 MongoDB 集合上的其他平面文件,但不适用于此平面文件。这是错误信息

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<timed exec> in <module>()

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in drop_duplicates(self, subset, keep, inplace)
   3096         """
   3097         inplace = validate_bool_kwarg(inplace, 'inplace')
-> 3098         duplicated = self.duplicated(subset, keep=keep)
   3099 
   3100         if inplace:

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in duplicated(self, subset, keep)
   3142 
   3143         vals = (self[col].values for col in subset)
-> 3144         labels, shape = map(list, zip(*map(f, vals)))
   3145 
   3146         ids = get_group_index(labels, shape, sort=False, xnull=False)

~/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py in f(vals)
   3131         def f(vals):
   3132             labels, shape = algorithms.factorize(
-> 3133                 vals, size_hint=min(len(self), _SIZE_HINT_LIMIT))
   3134             return labels.astype('i8', copy=False), len(shape)
   3135 

~/anaconda3/lib/python3.6/site-packages/pandas/core/algorithms.py in factorize(values, sort, order, na_sentinel, size_hint)
    558     uniques = vec_klass()
    559     check_nulls = not is_integer_dtype(original)
--> 560     labels = table.get_labels(values, uniques, 0, na_sentinel, check_nulls)
    561 
    562     labels = _ensure_platform_int(labels)

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_labels()

TypeError: unhashable type: 'list'

我想问题出在flat_something 文件上,但我想我需要做几次检查才能了解确切的问题。任何建议都会很有帮助

【问题讨论】:

    标签: python mongodb pandas


    【解决方案1】:

    提供cursor_list 的示例以及contacts 在没有错误或没有drop_duplicates() 时的样子。使用此示例,当传入的值之一是列表['a', 'b'] 时出现错误:

    In [2]: pd.DataFrame(pd.Series([['a', 'b'], 'c', ['a', 'b']]))  # ok
    Out[2]:
            0
    0  [a, b]
    1       c
    2  [a, b]
    
    In [3]: pd.DataFrame(pd.Series([['a', 'b'], 'c', ['a', 'b']])).drop_duplicates()  # error
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    

    所有列表值都需要转换为 hashable,这是 Python 用来确定删除重复值的唯一值。比如元组:

    In [5]: df = pd.DataFrame(pd.Series([['a', 'b'], 'c', ['a', 'b']]))  # duplicate
    
    In [6]: df.apply(lambda x: tuple(*x), axis=1)
    Out[6]:
    0    (a, b)
    1      (c,)
    2    (a, b)
    dtype: object
    
    In [7]: df.apply(lambda x: tuple(*x), axis=1).drop_duplicates()
    Out[7]:
    0    (a, b)
    1      (c,)
    dtype: object
    

    您可能需要分两步执行此操作:首先加载,然后应用+删除:

    contacts = pd.DataFrame(list(cursor_list))
    contacts = contacts.apply(lambda x: tuple(*x), axis=1).drop_duplicates()
    

    并确保在需要它的特定列上使用它,而不是全部。

    【讨论】:

    • 好的,谢谢,你能评论(lambda x: tuple(*x), axis=1)
    • 为此,请阅读apply()。它需要一个函数来按行或按列应用到数据框。 axis=1 指定对每一行应用函数。我正在使用lambda function 传递给apply。 (有关 Python lambda 函数的更多信息,请参阅链接的答案。)我将行中的每个值传递给 func,tuple(*x) 使用 argument expansion
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2013-10-22
    • 2013-01-23
    • 2017-06-21
    • 2017-12-27
    • 2011-07-29
    相关资源
    最近更新 更多