V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Furylord
V2EX  ›  Python

求助,为什么 Numpy 数组转 Tuple 时会出现小数点位数异常

  •  
  •   Furylord · 2016-07-28 10:59:21 +08:00 · 6766 次点击
    这是一个创建于 3046 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因为需要用到 Numpy Array 里的元素作为字典的 Key ,然而出现 TypeError: unhashable type: 'numpy.ndarray',所以先转 Tuple 再做 Key ,然而发现转 Tuple 时会出现小数点位数异常,举个例子:


    In [1]: a = [(40.1234,120.1111),(40.1233,120.1112),(40.1232,120.1113)]

    In [2]: b = numpy.array(a)

    In [3]: for i in a:
    ...: print(tuple(i))

    (40.1234, 120.1111)
    (40.1233, 120.1112)
    (40.1232, 120.1113)

    In [4]: for i in b:
    ...: print(tuple(i))

    (40.123399999999997, 120.11109999999999)
    (40.1233, 120.1112)
    (40.123199999999997, 120.1113)

    应该怎么处理呢
    13 条回复    2016-07-30 13:29:57 +08:00
    Furylord
        1
    Furylord  
    OP
       2016-07-28 10:59:36 +08:00
    用 round 貌似无效
    incompatible
        2
    incompatible  
       2016-07-28 11:10:31 +08:00
    因为你的元素是 float 类型的?
    想放到字典里,你应该把它转为 string 或者 decimal 类型做为 key 。
    ProfFan
        3
    ProfFan  
       2016-07-28 11:12:57 +08:00
    你看看你 ndarray 的 dtype
    ProfFan
        4
    ProfFan  
       2016-07-28 11:15:47 +08:00
    顺便

    ```
    >>> 40.123199999999997 == 40.1232
    True
    >>> a=40.123199999999997
    >>> a.as_integer_ratio()
    (22057962471791, 549755813888)
    >>> b=40.1232
    >>> b.as_integer_ratio()
    (22057962471791, 549755813888)
    >>>
    ```
    ProfFan
        5
    ProfFan  
       2016-07-28 11:24:21 +08:00
    试了一下,没跑了。 numpy 默认用的 float64 , python 32 , python 的精度太低。

    >>> for i in b:
    ... print(type(tuple(i)[0]))
    ...
    <class 'numpy.float64'>
    <class 'numpy.float64'>
    <class 'numpy.float64'>

    明白了吧
    ProfFan
        6
    ProfFan  
       2016-07-28 11:34:58 +08:00
    妈蛋弄错了,果然睡觉不能答题 23333

    只是显示不一样而已, numpy 默认显示高精度表示

    numpy.float64(40.1232)
    40.123199999999997
    Ahri
        7
    Ahri  
       2016-07-28 14:03:15 +08:00
    话说用 tuple of floats 当 hash key 不是很好的习惯呃,不知道楼主碰到什么样的需求。
    Furylord
        8
    Furylord  
    OP
       2016-07-28 15:38:55 +08:00
    @ProfFan
    谢谢,问题已经搞定啦
    Furylord
        9
    Furylord  
    OP
       2016-07-28 15:41:09 +08:00
    @Ahri
    用字典存储点与点的邻接矩阵,由于是稀疏的,所以考虑用字典的形式
    类似于 dict[(x1,y1)][(x2,y2)] = 1
    我是外行小白,不知道这种情况用什么样的数据结构会更合理呢
    necomancer
        10
    necomancer  
       2016-07-29 06:54:59 +08:00
    necomancer
        11
    necomancer  
       2016-07-29 06:56:44 +08:00
    @Furylord 数据量如果不大就直接 numpy.array 吧,如果只多几万个零是不是也能忍了~我现在是 numbapro 党,一般没有啥效率问题,都能忍,有些问题就懒得去再看 sparse 了。
    necomancer
        12
    necomancer  
       2016-07-29 07:03:22 +08:00
    @Furylord 如果想避免小数做索引,我建议做个 dict 把点标号,另一个用正常的矩阵表示,保证索引都是整数~
    ruoyu0088
        13
    ruoyu0088  
       2016-07-30 13:29:57 +08:00
    numpy 有自己的浮点数类型:numpy.float64 ,其转换为字符串的程序和 float 类型不同,因此显示不同。可以用 tolist()把数组转换为列表:

    print(tuple(i.tolist()))
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3519 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:42 · PVG 12:42 · LAX 20:42 · JFK 23:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.