如何在 IPython 笔记本的 Pandas DataFrame 列中左对齐文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25777037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I left justify text in a pandas DataFrame column in an IPython notebook
提问by Fred Mitchell
I am trying to format the output in an IPython notebook. I tried using the to_string function, and this neatly lets me eliminate the index column. But the textual data is right justified.
我正在尝试在 IPython 笔记本中格式化输出。我尝试使用 to_string 函数,这巧妙地让我消除了索引列。但是文本数据是正确的。
In [10]:
在[10]:
import pandas as pd
columns = ['Text', 'Value']
a = pd.DataFrame ({'Text': ['abcdef', 'x'], 'Value': [12.34, 4.2]})
print (a.to_string (index=False))
Text Value
abcdef 12.34
x 4.20
The same is true when just printing the dataframe.
仅打印数据帧时也是如此。
In [12]:
在[12]:
print (a)
Text Value
0 abcdef 12.34
1 x 4.20
The justify argument in the to_string function, surprisingly, only justifies the column heading.
令人惊讶的是, to_string 函数中的 justify 参数仅对齐列标题。
In [13]:
在[13]:
import pandas as pd
columns = ['Text', 'Value']
a = pd.DataFrame ({'Text': ['abcdef', 'x'], 'Value': [12.34, 4.2]})
print (a.to_string (justify='left', index=False))
Text Value
abcdef 12.34
x 4.20
How can I control the justification settings for individual columns?
如何控制单个列的对齐设置?
采纳答案by Brian Burns
If you're willing to use another library, tabulatewill do this -
如果你愿意使用另一个图书馆,制表会这样做 -
$ pip install tabulate
and then
进而
from tabulate import tabulate
df = pd.DataFrame ({'Text': ['abcdef', 'x'], 'Value': [12.34, 4.2]})
print(tabulate(df, showindex=False, headers=df.columns))
Text Value
------ -------
abcdef 12.34
x 4.2
It has various other output formats also.
它也有各种其他输出格式。
回答by unutbu
You could use a['Text'].str.len().max()to compute the length of the longest string in a['Text'], and use that number, N, in a left-justified formatter '{:<Ns}'.format:
您可以使用a['Text'].str.len().max()计算 中最长字符串的长度a['Text'],并N在左对齐的格式化程序中使用该数字'{:<Ns}'.format:
In [211]: print(a.to_string(formatters={'Text':'{{:<{}s}}'.format(a['Text'].str.len().max()).format}, index=False))
Text Value
abcdef 12.34
x 4.20
回答by JS.
I converted @unutbu's approach to a function so I could left-justify my dataframes.
我将@unutbu 的方法转换为一个函数,这样我就可以左对齐我的数据帧。
my_df = pd.DataFrame({'StringVals': ["Text string One", "Text string Two", "Text string Three"]})
def left_justified(df):
formatters = {}
for li in list(df.columns):
max = df[li].str.len().max()
form = "{{:<{}s}}".format(max)
formatters[li] = functools.partial(str.format, form)
return df.to_string(formatters=formatters, index=False)
So now this:
所以现在这个:
print(my_df.to_string())
StringVals
0 Text string One
1 Text string Two
2 Text string Three
becomes this:
变成这样:
print(left_justified(my_df))
StringVals
Text string One
Text string Two
Text string Three
Note, however, any non-string values in your dataframe will give you errors:
但是请注意,数据框中的任何非字符串值都会给您错误:
AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas
AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas
You'll have to pass different format strings to .to_string()if you want it to work with non-string values:
.to_string()如果您希望它使用非字符串值,则必须将不同的格式字符串传递给:
my_df2 = pd.DataFrame({'Booleans' : [False, True, True],
'Floats' : [1.0, 0.4, 1.5],
'StringVals': ["Text string One", "Text string Two", "Text string Three"]})
FLOAT_COLUMNS = ('Floats',)
BOOLEAN_COLUMNS = ('Booleans',)
def left_justified2(df):
formatters = {}
# Pass a custom pattern to format(), based on
# type of data
for li in list(df.columns):
if li in FLOAT_COLUMNS:
form = "{{!s:<5}}".format()
elif li in BOOLEAN_COLUMNS:
form = "{{!s:<8}}".format()
else:
max = df[li].str.len().max()
form = "{{:<{}s}}".format(max)
formatters[li] = functools.partial(str.format, form)
return df.to_string(formatters=formatters, index=False)
With floats and booleans:
使用浮点数和布尔值:
print(left_justified2(my_df2))
Booleans Floats StringVals
False 1.0 Text string One
True 0.4 Text string Two
True 1.5 Text string Three
Note this approach is a bit of a hack. Not only do you have to maintain column names in a separate lists, but you also have to best-guess at the data widths. Perhaps someone with better Pandas-Fu can demonstrate how to automate parsing the dataframe info to generate the formats automatically.
请注意,这种方法有点技巧性。您不仅必须在单独的列表中维护列名,而且还必须对数据宽度进行最佳猜测。也许有更好的 Pandas-Fu 的人可以演示如何自动解析数据帧信息以自动生成格式。
回答by Francis Trujillo
This works on Python 3.7 (functools is a part of that release now)
这适用于 Python 3.7(functools 现在是该版本的一部分)
# pylint: disable=C0103,C0200,R0205
from __future__ import print_function
import pandas as pd
import functools
@staticmethod
def displayDataFrame(dataframe, displayNumRows=True, displayIndex=True, leftJustify=True):
# type: (pd.DataFrame, bool, bool, bool) -> None
"""
:param dataframe: pandas DataFrame
:param displayNumRows: If True, show the number or rows in the output.
:param displayIndex: If True, then show the indexes
:param leftJustify: If True, then use technique to format columns left justified.
:return: None
"""
if leftJustify:
formatters = {}
for columnName in list(dataframe.columns):
columnType = type(columnName) # The magic!!
# print("{} => {}".format(columnName, columnType))
if columnType == type(bool):
form = "{{!s:<8}}".format()
elif columnType == type(float):
form = "{{!s:<5}}".format()
else:
max = dataframe[columnName].str.len().max()
form = "{{:<{}s}}".format(max)
formatters[columnName] = functools.partial(str.format, form)
print(dataframe.to_string(index=displayIndex, formatters=formatters), end="\n\n")
else:
print(dataframe.to_string(index=displayIndex), end="\n\n")
if displayNumRows:
print("Num Rows: {}".format(len(dataframe)), end="\n\n")

