У меня есть Pandas DataFrame, в котором один из столбцов содержит строковые элементы, а эти строковые элементы содержат новые строки, которые я хотел бы печатать буквально. Но они просто появляются как \n в выводе.

То есть я хочу напечатать это:

  pos     bidder
0   1
1   2
2   3  <- alice
       <- bob
3   4

Но вот что я получаю:

  pos            bidder
0   1
1   2
2   3  <- alice\n<- bob
3   4

Как я могу выполнить то, что я хочу? Могу ли я использовать DataFrame, или мне придется вернуться к ручной печати столбцов с добавками по одной строке за раз?

Вот что у меня есть на данный момент:

n = 4
output = pd.DataFrame({
    'pos': range(1, n+1),
    'bidder': [''] * n
})
bids = {'alice': 3, 'bob': 3}
used_pos = []
for bidder, pos in bids.items():
    if pos in used_pos:
        arrow = output.ix[pos, 'bidder']
        output.ix[pos, 'bidder'] = arrow + "\n<- %s" % bidder
    else:
        output.ix[pos, 'bidder'] = "<- %s" % bidder
print(output)
17
shadowtalker 17 Дек 2015 в 00:28

4 ответа

Лучший ответ

Из документа pandas.DataFrame documentmention:

Двумерная изменяемая по размеру, потенциально неоднородная структура табличных данных с помеченными осями (строки и столбцы). Арифметические операции выравнивают метки строк и столбцов. Можно рассматривать как контейнер, похожий на диктовку, для объектов Series. Основная структура данных панд

Таким образом, вы не можете иметь строку без индекса. Новая строка "\ n" не будет работать в DataFrame.

Вы можете перезаписать «pos» пустым значением и вывести следующий «bidder» в следующей строке. Но тогда index и 'pos' будут смещаться каждый раз, когда вы делаете это. Подобно:

  pos    bidder
0   1          
1   2          
2   3  <- alice
3        <- bob
4   5   

Таким образом, если у участника, названного 'frank', в качестве значения 4, он перезапишет 'bob'. Это может вызвать проблемы, когда вы добавите больше. Возможно, можно использовать DataFrame и написать код, чтобы обойти эту проблему, но, вероятно, стоит поискать другие решения.

Вот код для создания структуры вывода выше.

import pandas as pd

n = 5
output = pd.DataFrame({'pos': range(1, n + 1),
                      'bidder': [''] * n},
                      columns=['pos', 'bidder'])
bids = {'alice': 3, 'bob': 3}
used_pos = []
for bidder, pos in bids.items():
    if pos in used_pos:
        output.ix[pos, 'bidder'] = "<- %s" % bidder
        output.ix[pos, 'pos'] = ''
    else:
        output.ix[pos - 1, 'bidder'] = "<- %s" % bidder
        used_pos.append(pos)
print(output)

Изменить:

Другим вариантом является реструктуризация данных и вывода. Вы можете использовать pos в качестве столбцов и создать новую строку для каждого ключа / человека в данных. В приведенном ниже примере кода он печатает DataFrame со значениями NaN, замененными пустой строкой.

import pandas as pd

data = {'johnny\nnewline': 2, 'alice': 3, 'bob': 3,
        'frank': 4, 'lisa': 1, 'tom': 8}
n = range(1, max(data.values()) + 1)

# Create DataFrame with columns = pos
output = pd.DataFrame(columns=n, index=[])

# Populate DataFrame with rows
for index, (bidder, pos) in enumerate(data.items()):
    output.loc[index, pos] = bidder

# Print the DataFrame and remove NaN to make it easier to read.
print(output.fillna(''))

# Fetch and print every element in column 2
for index in range(1, 5):
    print(output.loc[index, 2])

Это зависит от того, что вы хотите сделать с данными, хотя. Удачи :)

3
oystein-hr 17 Дек 2015 в 14:01

В некоторой степени соответствует несортированному ответу:

import pandas as pd

# Save the original `to_html` function to call it later
pd.DataFrame.base_to_html = pd.DataFrame.to_html
# Call it here in a controlled way
pd.DataFrame.to_html = (
    lambda df, *args, **kwargs: 
        (df.base_to_html(*args, **kwargs)
           .replace(r"\n", "<br/>"))
)

Таким образом, вам не нужно вызывать какие-либо явные функции в записных книжках Jupyter, так как to_html вызывается изнутри. Если вам нужна оригинальная функция, вызовите base_to_html (или как вы ее назвали).

Я использую jupyter 1.0.0, notebook 5.7.6.

2
Roger d'Amiens 15 Мар 2019 в 14:02

Использование свойств панд .set_properties() и CSS white-space

[Для использования в записных книжках IPython]

Другим способом будет использование pandas.io.formats.style.Styler.set_properties () и метод CSS свойство "white-space": "pre-wrap":

from IPython.display import display

# Assuming the variable df contains the relevant DataFrame
display(df.style.set_properties(**{
    'white-space': 'pre-wrap',
})

Чтобы текст оставался выровненным по левому краю, вы можете добавить 'text-align': 'left', как показано ниже:

from IPython.display import display

# Assuming the variable df contains the relevant DataFrame
display(df.style.set_properties(**{
    'text-align': 'left',
    'white-space': 'pre-wrap',
})

4
yongjieyongjie 4 Июл 2019 в 05:53

Если вы пытаетесь сделать это в блокноте ipython, вы можете сделать:

from IPython.display import display, HTML

def pretty_print(df):
    return display( HTML( df.to_html().replace("\\n","<br>") ) )
14
David Marx 26 Фев 2018 в 21:36