如何制作 Pandas DataFrame (Python) 以二维 (2-D) 矩阵格式显示每个单元格
how to make Pandas DataFrame (Python) to display each cell in a two dimensional (2-D) matrix format
我正在尝试使用在 Python 中导入的 Matlab 结构创建二维 (2-D) 数据结构。
当我使用pandas.DataFrame时,每个单元格都包含一个矩阵,但是它们以列表格式显示。我正在尝试将其更改为 Matrix 格式。
Python 中的 DataFrame 使用以下代码看起来很相似:
(但是,它不一样,因为真实数据是从 Matlab 导入的,并且具有不同的类型,我无法使用 python 重新创建它)
import pandas as pd
k=[[0,1,2,3,4,5,6]]
df=pd.DataFrame(k)
df[:] = df[:].astype('object')
df.at[0,0] = [[1]]
df.at[0,1] = [[1.0,2.0],[2.0,4.0],[8.0,3.0],[9.0,7.0]]
df.at[0,2] = [[0.487],[1.532],[1.544],[1.846]]
df.at[0,3] = [[3.0]]
df.at[0,4] = [[3.0]]
df.at[0,5] = [[-1]]
df.at[0,6] = [[]]
display(df)
结果在:
(您也可以通过 运行 以下代码段找到类似的结果。)
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>[[1]]</td>
<td>[[1.0, 2.0], [2.0, 4.0], [8.0, 3.0], [9.0, 7.0]]</td>
<td>[[0.487], [1.5326], [1.544], [1.846]]</td>
<td>[[3.0]]</td>
<td>[[3.0]]</td>
<td>[[-1]]</td>
<td>[[]]</td>
</tr>
</tbody>
</table>
如您所见,每个单元格显示为列表,即:
(您也可以通过 运行 以下代码段找到类似的结果。)
<body>
[[1.0, 2.0], [2.0, 4.0], [8.0, 3.0], [9.0, 7.0]]
</body>
我正在尝试将其更改为:
(您也可以通过 运行 以下代码段找到类似的结果。)
.matrix {
position: relative;
}
.matrix:before, .matrix:after {
content: "";
position: absolute;
top: 0;
border: 1px solid #000;
width: 6px;
height: 100%;
}
.matrix:before {
left: -10px;
border-right: -0;
}
.matrix:after {
right: -10px;
border-left: 0;
}
<div align=center>
<table class="matrix">
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
<tr>
<td>8</td>
<td>3</td>
</tr>
<tr>
<td>9</td>
<td>7</td>
</tr>
</table>
</div>
谢谢。
Pandas 的默认输出打印机无法满足您的需求。但是,您可以使用 pandas.Styler
创建 HTML,然后将 HTML 插入 DataFrame,然后使用您提供的必要 CSS 样式呈现 HTML :
data = [
[[1]],
[[1.0,2.0],[2.0,4.0],[8.0,3.0],[9.0,7.0]],
[[0.487],[1.532],[1.544],[1.846]],
[[3.0]],
[[3.0]],
[[-1]],
]
df = pd.DataFrame([
[(pd.DataFrame(x)
.style
.hide_index()
.hide_columns()
.set_table_attributes('class="matrix"')
.to_html()
) for x in data]
], dtype="object")
df.style.set_table_styles([
{"selector": ".matrix", "props": "position: relative;"},
{"selector": ".matrix:before, .matrix:after",
"props": 'content: ""; position: absolute; top: 0; border: 1px solid #000; width: 6px; height: 100%;'
},
{"selector": ".matrix:before", "props": "left: -0px; border-right: -0;"},
{"selector": ".matrix:after", "props": "right: -0px; border-left: 0;"}
])
@Attack68,这是我在回复你漂亮的回答时提到的代码。
请记住,正如我提到的,真实数据是从 Matlab 结构中导入的。这意味着它不适用于我在问题本身中提供的数据,但适用于使用 scipy.io 导入到 python 的 Matlab 结构。
我在 @Valdi_Bo 对 and @Paul Panzer answer on 的回答的帮助下编写了这段代码。
df = pd.DataFrame(data)
import re
def pretty_col(data):
data=np.array(data)
if data.size <= 1:
return format(data)
else:
return format(data[:, None])[1:-1].replace('[', '\u23A1', 1).replace(' [', '\u23A2', data.size-2).replace(' [', '\u23A3').replace(']', '\u23A4', 1).replace(']', '\u23A5', data.size-2).replace(']', '\u23A6')
def pretty_cols(data, comma=False):
if comma:
f='\n'.join(line[0] + line + line[-1] for line in map(str.join, data.shape[0] // 2 * (' ',) + (', ',) + (data.shape[0] - 1) // 2 * (' ',), zip(*map(str.split, map(pretty_col, data.T), data.shape[1]*('\n',)))))
else:
f='\n'.join(line[0] + line + line[-1] for line in map(''.join, zip(*map(str.split, map(pretty_col, data.T), data.shape[1]*('\n',)))))
return f
def myFmt(txt):
if txt=="":
return "[]"
else:
q=r'<font">bananas\n</font>'
q=q.replace("bananas", repr(txt))
q=q.replace("'", '')
return q.replace(r'\n', '<br>')
def ttest(x):
for i,k in enumerate(x):
for j,l in enumerate(k):
x[i][j]=float(format(l, '.2f'))
return x
def transform(tdf,prec):
for col in tdf.columns:
tdf[col] = tdf[col].apply(pretty_cols)
for j in range(len(tdf[col])):
tdf[col][j]=fixing_newline(tdf[col][j],prec)
print(df[df.columns[0]])
def fixing_newline(string,prec):
string=string.replace("⎡⎡", ' aa ').replace("⎤⎤", ' bb ').replace("\n", ' cc ').replace("⎢⎢", ' dd ').replace("⎥⎥", ' ee ').replace("⎣⎣", ' ff ').replace("⎦⎦", ' gg ').replace("[[", ' hh ').replace("]]", ' kk ')
chunks = string.split(' ')
string=""
for i,k in enumerate(chunks):
try:
string+=str("{:."+str(prec)+"f}").format(float(k))
except ValueError:
string+=k
string=string.replace("aa", "⎡⎡").replace("bb", '⎤⎤').replace("cc", '\n').replace("dd", '⎢⎢').replace("ee", '⎥⎥').replace("ff", '⎣⎣').replace("gg", '⎦⎦').replace("hh", '[[').replace("kk", ']]')
return string
transform(df,3)
df=df.style.format(myFmt)
display(df)
这将导致如下结果:
Results(需要内联图像方面的帮助,因为我没有足够的声誉。)
然而,该代码一点也不高效,而且始终无法正常运行。
我正在尝试使用在 Python 中导入的 Matlab 结构创建二维 (2-D) 数据结构。
当我使用pandas.DataFrame时,每个单元格都包含一个矩阵,但是它们以列表格式显示。我正在尝试将其更改为 Matrix 格式。
Python 中的 DataFrame 使用以下代码看起来很相似: (但是,它不一样,因为真实数据是从 Matlab 导入的,并且具有不同的类型,我无法使用 python 重新创建它)
import pandas as pd
k=[[0,1,2,3,4,5,6]]
df=pd.DataFrame(k)
df[:] = df[:].astype('object')
df.at[0,0] = [[1]]
df.at[0,1] = [[1.0,2.0],[2.0,4.0],[8.0,3.0],[9.0,7.0]]
df.at[0,2] = [[0.487],[1.532],[1.544],[1.846]]
df.at[0,3] = [[3.0]]
df.at[0,4] = [[3.0]]
df.at[0,5] = [[-1]]
df.at[0,6] = [[]]
display(df)
结果在:
(您也可以通过 运行 以下代码段找到类似的结果。)
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>[[1]]</td>
<td>[[1.0, 2.0], [2.0, 4.0], [8.0, 3.0], [9.0, 7.0]]</td>
<td>[[0.487], [1.5326], [1.544], [1.846]]</td>
<td>[[3.0]]</td>
<td>[[3.0]]</td>
<td>[[-1]]</td>
<td>[[]]</td>
</tr>
</tbody>
</table>
如您所见,每个单元格显示为列表,即:
(您也可以通过 运行 以下代码段找到类似的结果。)
<body>
[[1.0, 2.0], [2.0, 4.0], [8.0, 3.0], [9.0, 7.0]]
</body>
我正在尝试将其更改为:
(您也可以通过 运行 以下代码段找到类似的结果。)
.matrix {
position: relative;
}
.matrix:before, .matrix:after {
content: "";
position: absolute;
top: 0;
border: 1px solid #000;
width: 6px;
height: 100%;
}
.matrix:before {
left: -10px;
border-right: -0;
}
.matrix:after {
right: -10px;
border-left: 0;
}
<div align=center>
<table class="matrix">
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
<tr>
<td>8</td>
<td>3</td>
</tr>
<tr>
<td>9</td>
<td>7</td>
</tr>
</table>
</div>
谢谢。
Pandas 的默认输出打印机无法满足您的需求。但是,您可以使用 pandas.Styler
创建 HTML,然后将 HTML 插入 DataFrame,然后使用您提供的必要 CSS 样式呈现 HTML :
data = [
[[1]],
[[1.0,2.0],[2.0,4.0],[8.0,3.0],[9.0,7.0]],
[[0.487],[1.532],[1.544],[1.846]],
[[3.0]],
[[3.0]],
[[-1]],
]
df = pd.DataFrame([
[(pd.DataFrame(x)
.style
.hide_index()
.hide_columns()
.set_table_attributes('class="matrix"')
.to_html()
) for x in data]
], dtype="object")
df.style.set_table_styles([
{"selector": ".matrix", "props": "position: relative;"},
{"selector": ".matrix:before, .matrix:after",
"props": 'content: ""; position: absolute; top: 0; border: 1px solid #000; width: 6px; height: 100%;'
},
{"selector": ".matrix:before", "props": "left: -0px; border-right: -0;"},
{"selector": ".matrix:after", "props": "right: -0px; border-left: 0;"}
])
@Attack68,这是我在回复你漂亮的回答时提到的代码。
请记住,正如我提到的,真实数据是从 Matlab 结构中导入的。这意味着它不适用于我在问题本身中提供的数据,但适用于使用 scipy.io 导入到 python 的 Matlab 结构。
我在 @Valdi_Bo 对
df = pd.DataFrame(data)
import re
def pretty_col(data):
data=np.array(data)
if data.size <= 1:
return format(data)
else:
return format(data[:, None])[1:-1].replace('[', '\u23A1', 1).replace(' [', '\u23A2', data.size-2).replace(' [', '\u23A3').replace(']', '\u23A4', 1).replace(']', '\u23A5', data.size-2).replace(']', '\u23A6')
def pretty_cols(data, comma=False):
if comma:
f='\n'.join(line[0] + line + line[-1] for line in map(str.join, data.shape[0] // 2 * (' ',) + (', ',) + (data.shape[0] - 1) // 2 * (' ',), zip(*map(str.split, map(pretty_col, data.T), data.shape[1]*('\n',)))))
else:
f='\n'.join(line[0] + line + line[-1] for line in map(''.join, zip(*map(str.split, map(pretty_col, data.T), data.shape[1]*('\n',)))))
return f
def myFmt(txt):
if txt=="":
return "[]"
else:
q=r'<font">bananas\n</font>'
q=q.replace("bananas", repr(txt))
q=q.replace("'", '')
return q.replace(r'\n', '<br>')
def ttest(x):
for i,k in enumerate(x):
for j,l in enumerate(k):
x[i][j]=float(format(l, '.2f'))
return x
def transform(tdf,prec):
for col in tdf.columns:
tdf[col] = tdf[col].apply(pretty_cols)
for j in range(len(tdf[col])):
tdf[col][j]=fixing_newline(tdf[col][j],prec)
print(df[df.columns[0]])
def fixing_newline(string,prec):
string=string.replace("⎡⎡", ' aa ').replace("⎤⎤", ' bb ').replace("\n", ' cc ').replace("⎢⎢", ' dd ').replace("⎥⎥", ' ee ').replace("⎣⎣", ' ff ').replace("⎦⎦", ' gg ').replace("[[", ' hh ').replace("]]", ' kk ')
chunks = string.split(' ')
string=""
for i,k in enumerate(chunks):
try:
string+=str("{:."+str(prec)+"f}").format(float(k))
except ValueError:
string+=k
string=string.replace("aa", "⎡⎡").replace("bb", '⎤⎤').replace("cc", '\n').replace("dd", '⎢⎢').replace("ee", '⎥⎥').replace("ff", '⎣⎣').replace("gg", '⎦⎦').replace("hh", '[[').replace("kk", ']]')
return string
transform(df,3)
df=df.style.format(myFmt)
display(df)
这将导致如下结果: Results(需要内联图像方面的帮助,因为我没有足够的声誉。)
然而,该代码一点也不高效,而且始终无法正常运行。