web-dev-qa-db-ja.com

Pandas DataFrameの文字列内に改行をきれいに出力する

Pandas DataFrameがあり、列の1つに文字列要素が含まれていて、それらの文字列要素に文字通り印刷したい新しい行が含まれています。しかし、これらは\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を使用できますか、またはパディングされた列を一度に1行ずつ手動で印刷するように戻す必要がありますか?

これが私がこれまでに持っているものです:

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)
12
shadowtalker

Pandas.DataFrameから documentation

ラベル付けされた軸(行と列)を持つ2次元のサイズ変更可能な、潜在的に異種の表形式のデータ構造。算術演算は、行ラベルと列ラベルの両方に整列します。 Seriesオブジェクトのdictのようなコンテナと考えることができます。プライマリpandasデータ構造

したがって、インデックスなしで行を作成することはできません。改行 "\ n"はDataFrameでは機能しません。

'pos'を空の値で上書きし、次の 'bidder'を次の行に出力することができます。ただし、インデックスと「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)

編集:

もう1つのオプションは、データと出力を再構築することです。列としてposを使用し、データ内のキー/個人ごとに新しい行を作成できます。以下のコード例では、NaN値が空の文字列に置き換えられたDataFrameを出力します。

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

Ipythonノートブックでこれを実行しようとしている場合は、次のことができます。

from IPython.display import display, HTML

def pretty_print(df):
    return display( HTML( df.to_html().replace("\\n","<br>") ) )
13
unsorted

pandas .set_properties()およびCSSwhite-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',
})

2
yongjieyongjie

Unsortedの答えとある程度一致しています:

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/>"))
)

このように、to_htmlは内部で呼び出されるため、Jupyterノートブックで明示的な関数を呼び出す必要はありません。元の関数が必要な場合は、base_to_html(または名前を付けたもの)を呼び出します。

jupyter 1.0.0notebook 5.7.6を使用しています。

1
Roger d'Amiens