javascript - 如何在熊猫数据框输出中定义索引或点击行数?
问题描述
我想在 ipywidgets 上制作一些表格,它在其输入中显示特定行的熊猫数据框的值。
为了使行选择和以更具交互性的形式显示,我需要以某种方式处理在显示的数据框中单击。实际上,我希望能够识别最后点击的数据框行的索引或数量。
PS
我见过像 ipysheet 和其他工具这样的工具,但我认为它们仍然太新,尽管 ipysheet 将来可能会非常强大。所以这些工具不适用于这项任务。
解决方案
我有类似的问题,qgrid
对我来说太过分了。
jupyter 中的工作原理(灵感来自在 html table 中的每一行添加点击功能):
注入的脚本将处理程序添加到数据框表的每个单元格(由
id='T_table'
通过Styler.set_uuid
函数标记)。单击单元格时的典型处理程序:
查找指定的输入元素(隐藏并由占位符“未定义”标记),
为单击的单元格的类名设置找到的输入的 value 属性,
- 触发“更改”事件。
之后,单击单元格的类名(pandas 使它们包含必要的行/列信息)可用于 ipywidgets 框架,并且可以在 python 中处理。
评论:
在调用脚本之前需要一定的超时时间。对于更大的表,所需的超时可能会更大。
逻辑有点复杂,因为我使用的将 js-values 带入 python 世界的方法是通过
ipywidgets.Text
.添加 2.1 项以防 DOM 在启动后重新渲染。
import pandas as pd
import ipywidgets as wgt
from IPython.display import display, HTML
import re
# javascript-part
script = """
<script>
var input
var xpath = "//input[contains(@placeholder,'undefined')]";
function addHandlers() {
input = document.evaluate(xpath, document, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
input.setAttribute("hidden","");
var table = document.querySelector("#T_table");
var headcells = [].slice.call(table.getElementsByTagName("th"));
var datacells = [].slice.call(table.getElementsByTagName("td"));
var cells = headcells.concat(datacells);
for (var i=0; i < cells.length; i++) {
var createClickHandler = function(cell) {
return function() {
input = document.evaluate(xpath, document, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
input.value = cell.className;
var event = new Event('change', { bubbles: true });
input.dispatchEvent(event);
}}
cells[i].onclick = createClickHandler(cells[i]);
};
}
window.onload = setTimeout(addHandlers, 500);
</script>
"""
display(HTML(script))
# ipywidgets-part
newdf = pd.DataFrame(data={
'1': [11,21,31,41], '2': [12,22,32,42], '3': [13,23,33,43],
'4': [14,24,34,44], '5': [15,25,35,45], '6': [16,26,36,46],
'7': [17,27,37,47], '8': [18,28,38,48], '9': [19,29,39,49],
'10': [110,210,310,410],'11': [111,211,311,411],
})
html = newdf.style.\
set_uuid('table')
def on_change(change):
cls = change['new'].split(' ')
if len(cls) == 2:
place.value, row.value = cls
col.value = '0'
elif len(cls) == 3:
place.value, txtrow, txtcol = cls
res = re.search(r'\d+',txtrow).group(0)
row.value = str(int(res)+1)
res = re.search(r'\d+',txtcol).group(0)
col.value = str(int(res)+1)
else:
place.value, row.value, col.value = ['unknown']*3
status = wgt.Text(placeholder='undefined',layout={'font-size':'6px'})
status.observe(on_change,names=['value'])
table = wgt.Output()
with table: display(html)
layout = {'width':'192px'}
row = wgt.Text(layout=layout,description='row')
col = wgt.Text(layout=layout,description='col')
place = wgt.Text(layout=layout,description='place')
body = wgt.HBox([table,wgt.VBox([place,row,col])])
wgt.VBox([body,status])
推荐阅读
- r - 在 R 中将纳秒转换为 hh:mm:ss.ms
- javascript - 在 Visual Studio Code 中使用装饰器时出错
- http-live-streaming - IDM 不开始下载的 JWplayer 背后的技术细节是什么?
- mysql - 根据时间戳的最大列值
- amazon-s3 - Monitor S3 - 如果自最后一个文件写入后超过 5 分钟,则发送警报
- android - Flutter 无法处理方法调用 E/MethodChannel#flutter/platform(8279):
- wordpress - 我们可以在 WordPress 网站旁边有一个 ASP.NET Core 应用程序吗?
- ios - 集合视图规模流布局
- visual-studio - 将 Visual Studio 解决方案连接到不同的 Azure Devops 项目
- oracle - Oracle 12 获取更改表(插入、删除或更新记录)