在iPython中设置千位分隔符而不进行字符串格式化

时间:2016-03-06 12:30:42

标签: python formatting ipython

我正在寻找以下问题的答案超过4个小时了。大多数页面都表示字符串格式化这不是我想要的。

我想在IPython中为整数和浮点数的千位分隔符设置一个参数。该选项应仅影响数字在交互式会话中的显示方式。我想设置一次参数。我需要为每个新输出做一些格式化的所有解决方案根本不能满足我的需要。我做了一些探索性的数据分析,不想为每一行代码都打扰数字格式。

格式应该与所有整数和浮点数一起使用,包括那些存储在numpy数组或pandas数据帧中的格式。

对于那些熟悉Mathematica的人,我指出了如何在Mathematica中做到这一点:转到preferences => appearance => numbers =>格式。在那里,您可以“启用自动数字格式化”并选择“数字块分隔符”。

示例:如果我在ipython会话中输入“600 + 600”,我想要以下输出:1'200(其中'将是我的千位分隔符)。

我在Spyder和IPython笔记本中使用IPython控制台。谢谢。

1 个答案:

答案 0 :(得分:10)

如果您使用str.formatnumpy.set_printoptions,则可以全局设置一次:

import numpy as np
import IPython

frm = get_ipython().display_formatter.formatters['text/plain']


def thousands(arg, p, cycle):
    p.text("{:,}".format(arg).replace(",","'"))

frm.for_type(int, thousands)
frm.for_type(float, thousands)

np.set_printoptions(formatter={'int_kind': lambda x: '{:,}'.format(x).replace(",","'")})

 np.set_printoptions(formatter={'float_kind': lambda x: '{:,}'.format(x).replace(",","'")})

frm = get_ipython().display_formatter.formatters['text/plain']
frm.for_type(int, thousands)
frm.for_type(float, thousands)

它不包括所有基础,但您可以添加更多逻辑:

In [2]: arr = np.array([12345,12345])

In [3]: arr
Out[3]: array([12'345, 12'345])

In [4]: 123456
Out[4]: 123'456

In [5]: 123456.343
Out[5]: 123'456.343

您可以将它添加到startup.py脚本中,确保将PYTHONSTARTUP设置为指向该文件,以便在启动ipython时加载它:

~$ ipython2
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
Type "copyright", "credits" or "license" for more information.

IPython 4.0.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
(.startup.py)
(imported datetime, os, pprint, re, sys, time,np,pd)

In [1]: arr = np.array([12345,12345])

In [2]: arr
Out[2]: array([12'345, 12'345])

In [3]: 12345
Out[3]: "12'345"

对于pandas,您似乎可以使用set_option

设置display.float_format
In [22]: pd.set_option("display.float_format",lambda x: "{:,}".format(x).replace(",","'"))

In [23]: pd.DataFrame([[12345.3,12345.4]])
Out[23]: 
         0        1
0 12'345.3 12'345.4

基于this answer,对于大熊猫的后续版本,我们需要更改pandas.core.format.IntArrayFormatter

所以完整的启动脚本应该是这样的:

import IPython

import numpy as np
import pandas as pd

# numpy
np.set_printoptions(formatter={'float_kind': lambda x: '{:,}'.format(x).replace(",", "'"),
                          'int_kind': lambda x: '{:,}'.format(x).replace(",", "'")})


# pandas
class IntFormatter(pd.core.format.GenericArrayFormatter):
    pd.set_option("display.float_format", lambda x: "{:,}".format(x).replace(",", "'"))

    def _format_strings(self):
        formatter = self.formatter or (lambda x: ' {:,}'.format(x).replace(",", "'"))
        fmt_values = [formatter(x) for x in self.values]
        return fmt_values


pd.core.format.IntArrayFormatter = IntFormatter


# general
def thousands(arg, p, cycle):
    p.text("{:,}".format(arg).replace(",","'"))


frm = get_ipython().display_formatter.formatters['text/plain']
frm.for_type(int, thousands)
frm.for_type(float, thousands)

这似乎涵盖了你想要的大部分内容:

IPython 4.0.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
(.startup.py)
(imported datetime, os, pprint, re, sys, time,np,pd)

In [1]: pd.DataFrame([[12345,12345]])
Out[1]: 
        0       1
0  12'345  12'345

In [2]: pd.DataFrame([[12345,12345.345]])
Out[2]: 
        0          1
0  12'345 12'345.345

In [3]: np.array([12345,678910])
Out[3]: array([12'345, 678'910])

In [4]: np.array([12345.321,678910.123])
Out[4]:  array([12'345.321, 678'910.123])


In [5]: 100000
Out[5]: 100'000

In [6]: 100000.123
Out[6]: 100'000.123

In [7]: 10000000
Out[7]: 10'000'000