Вывод списков в виде табличных данных
Я совсем новичок в языке Python и сейчас сталкиваюсь с трудностями при форматировании данных для печатного вывода.
У меня есть один список, который используется для двух заголовков, и матрица, которая должна представлять содержимое таблицы. Вот так:
teams_list = ["Man Utd", "Man City", "T Hotspur"]
data = np.array([[1, 2, 1],
[0, 1, 0],
[2, 4, 2]])
Обратите внимание, что имена заголовков не обязательно имеют одинаковую длину. Все элементарные данные — это целые числа.
Теперь я хочу представить эти данные в табличном формате, что-то вроде этого:
Man Utd Man City T Hotspur
Man Utd 1 0 0
Man City 1 1 0
T Hotspur 0 1 2
У меня есть предчувствие, что для этого должна быть подходящая структура данных, но я не могу её найти. Я пробовал использовать словарь и форматирование при выводе, пытался использовать циклы с отступами, а также пробовал вывод в виде строк.
Я уверен, что должен быть очень простой способ сделать это, но, вероятно, я просто не замечаю его из-за недостатка опыта.
5 ответ(ов)
Чтобы создать DataFrame в Pandas с заданными данными и индексами, вы можете использовать конструкцию pd.DataFrame()
, как показано в вашем примере. Вот как это можно реализовать:
import pandas as pd
# Создаем данные в виде вложенного списка
data = [[1, 2, 1],
[0, 1, 0],
[2, 4, 2]]
# Список команд
teams_list = ['Man Utd', 'Man City', 'T Hotspur']
# Создаем DataFrame с заданными данными и индексами
df = pd.DataFrame(data, index=teams_list, columns=teams_list)
print(df)
В результате вы получите DataFrame с данными, где строки и столбцы будут соответствовать командам:
Man Utd Man City T Hotspur
Man Utd 1 2 1
Man City 0 1 0
T Hotspur 2 4 2
Таким образом, вы можете легко создавать матрицы (таблицы) с подписями как для строк, так и для столбцов, используя pd.DataFrame()
в Pandas.
Python на самом деле делает это довольно просто.
Вы можете использовать следующий код:
for i in range(10):
print '%-12i%-12i' % (10 ** i, 20 ** i)
На выходе получится:
1 1
10 20
100 400
1000 8000
10000 160000
100000 3200000
1000000 64000000
10000000 1280000000
100000000 25600000000
1000000000 512000000000
Знак %
внутри строки фактически является символом формата, а символы, следующие за ним, указывают Python, каким образом следует отформатировать данные. Знак %
снаружи и после строки говорит Python, что вы собираетесь использовать предыдущую строку как строку формата, и что последующие данные должны быть вставлены в указанный формат.
В данном случае я использовал "%-12i" дважды. Разберем каждую часть:
'-' (выравнивание по левому краю)
'12' (количество пространства, отведенное для этой части вывода)
'i' (мы печатаем целое число)
Дополнительную информацию можно найти в документации: https://docs.python.org/2/library/stdtypes.html#string-formatting
Обновление ответа Свена Марнаха для работы в Python 3.4:
row_format = "{:>15}" * (len(teams_list) + 1)
print(row_format.format("", *teams_list))
for team, row in zip(teams_list, data):
print(row_format.format(team, *row))
Этот код создает строковый формат для вывода таблицы, где каждая колонка занимает фиксированное пространство. Метод format
используется для замены плейсхолдеров в строке. Мы сначала выводим заголовок с названиями команд из списка teams_list
, а затем для каждой команды и соответствующей строки данных выводим отформатированное представление. Убедитесь, что ваши данные в переменной data
имеют правильную структуру, соответствующую количеству команд.
Простой способ сделать это — пройтись по всем столбцам, измерить их ширину, создать шаблон строки для максимальной ширины, а затем напечатать строки. Это не совсем то, что вам нужно, поскольку в этом случае вам сначала нужно поместить заголовки внутри таблицы, но я думаю, что это может быть полезно для кого-то другого.
Вот пример кода:
table = [
["", "Man Utd", "Man City", "T Hotspur"],
["Man Utd", 1, 0, 0],
["Man City", 1, 1, 0],
["T Hotspur", 0, 1, 2],
]
def print_table(table):
longest_cols = [
(max([len(str(row[i])) for row in table]) + 3)
for i in range(len(table[0]))
]
row_format = "".join(["{:>" + str(longest_col) + "}" for longest_col in longest_cols])
for row in table:
print(row_format.format(*row))
Использовать его можно так:
>>> print_table(table)
Man Utd Man City T Hotspur
Man Utd 1 0 0
Man City 1 1 0
T Hotspur 0 1 2
Этот подход обеспечивает аккуратное выравнивание столбцов, что делает вывод таблицы более читаемым.
Когда я работаю с таблицами, мне бы хотелось иметь некоторый контроль над форматированием. В частности, я хочу, чтобы заголовки ячеек выглядели иначе, чем ячейки тела, а ширина столбцов была бы ровно такой, какой они требуют. Вот мое решение:
def format_matrix(header, matrix,
top_format, left_format, cell_format, row_delim, col_delim):
table = [[''] + header] + [[name] + row for name, row in zip(header, matrix)]
table_format = [['{:^{}}'] + len(header) * [top_format]] \
+ len(matrix) * [[left_format] + len(header) * [cell_format]]
col_widths = [max(
len(format.format(cell, 0))
for format, cell in zip(col_format, col))
for col_format, col in zip(zip(*table_format), zip(*table))]
return row_delim.join(
col_delim.join(
format.format(cell, width)
for format, cell, width in zip(row_format, row, col_widths))
for row_format, row in zip(table_format, table))
print(format_matrix(['Man Utd', 'Man City', 'T Hotspur', 'Really Long Column'],
[[1, 2, 1, -1], [0, 1, 0, 5], [2, 4, 2, 2], [0, 1, 0, 6]],
'{:^{}}', '{:<{}}', '{:>{}.3f}', '\n', ' | '))
Вот результат:
| Man Utd | Man City | T Hotspur | Really Long Column
Man Utd | 1.000 | 2.000 | 1.000 | -1.000
Man City | 0.000 | 1.000 | 0.000 | 5.000
T Hotspur | 2.000 | 4.000 | 2.000 | 2.000
Really Long Column | 0.000 | 1.000 | 0.000 | 6.000
Данный код создает отформатированную матрицу, где заголовки и ячейки содержимого имеют разные виды форматирования, и ширина каждого столбца соответствует его содержимому.
Как изменить порядок столбцов в DataFrame?
'pip' не распознан как командa внутреннего или внешнего формата
Почему statistics.mean() работает так медленно?
Преобразование строки даты JSON в datetime в Python
Есть ли разница между поднятием экземпляра класса Exception и самого класса Exception?