Вам нужно сделать второй объект groupby, который группируется по состояниям, а затем использовать метод div
:
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame({'state': ['CA', 'WA', 'CO', 'AZ'] * 3,
'office_id': list(range(1, 7)) * 2,
'sales': [np.random.randint(100000, 999999) for _ in range(12)]})
state_office = df.groupby(['state', 'office_id']).agg({'sales': 'sum'})
state = df.groupby(['state']).agg({'sales': 'sum'})
state_office.div(state, level='state') * 100
sales
state office_id
AZ 2 16.981365
4 19.250033
6 63.768601
CA 1 19.331879
3 33.858747
5 46.809373
CO 1 36.851857
3 19.874290
5 43.273852
WA 2 34.707233
4 35.511259
6 29.781508
level='state'
kwarg в div
сообщает pandas для трансляции / присоедините базу данных к значениям на уровне state
индекса.
Ответ: Итак, это техника, с которой мне очень нравится. Не требует слишком много , чтобы определить идентификатор компонента. Помните, что все это означает, что вы можете знать id
компонента из любой точки вашей страницы, а не только из самого реального компонента. Это ключ. Я нажимаю кнопку, запускаю функцию javascript, и она должна иметь доступ к любому другому компоненту, а не к той, которая его запускала.
Это решение не требует «щелчка правой кнопкой мыши» и видит, что идентификатор. Этот тип решения является хрупким, поскольку идентификатор динамически генерируется, и если я меняю страницу, мне придется каждый раз проходить через эту бессмыслицу.
Итак, вот пример того, как это можно сделать.
Предположения: У меня есть * .xhtml (может быть * .jsp), и я определил бэк-файл. Я также использую JSF 2.0.
*. Xhtml page
<script>
function myFunc() {
var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")
alert("The email address is: " + inputText.value );
}
</script>
<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.java
UIInput emailAddyInputText;
Обязательно создайте свой приемник / сеттер для этого свойства.
Я знаю, что это не способ JSF, но если вы хотите избежать боли в ИД, вы можете установить специальный класс CSS для селектора. Просто убедитесь, что используете хорошее имя, чтобы, когда кто-то читает имя класса, ясно, что он использовался для этой цели.
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
В вашем JavaScript:
jQuery('.emailAddressesForSelector');
Конечно, вам все равно придется вручную управлять уникальностью имени класса. Я считаю, что это поддерживается, если вы не используете это в компонентах многократного использования. В этом случае вы можете сгенерировать имена классов с помощью соглашения.
Вам нужно точно указать идентификатор, назначенный JSF в сгенерированном HTML-выходе. Щелкните правой кнопкой мыши страницу в своем веб-браузере и выберите View Source . Это точно код HTML, который видит JS (вы знаете, JS работает в webbrowser и перехватывает дерево HTML DOM).
Учитывая
<h:form>
<h:inputText id="emailAddresses" ... />
Он будет выглядеть примерно так :
<form id="j_id0">
<input type="text" id="j_id0:emailAddress" ... />
Где j_id0
- сгенерированный идентификатор сгенерированного элемента HTML <form>
.
Вы предпочли бы дать все JSF NamingContainer
фиксированных id
, так что JSF не автогенерирует их. <h:form>
является одним из них.
<h:form id="formId">
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
Таким образом, форма не получит автогенерированный ID, такой как j_id0
, и поле ввода получит фиксированный идентификатор formId:emailAddress
. Вы можете просто ссылаться на него как таковой в JS.
var input = document.getElementById('formId:emailAddress');
С этого момента вы можете продолжать использовать JS-код, как обычно. Например. получая значение через input.value
.
Обновление согласно вашему обновлению: вы неправильно поняли статью в блоге. Специальная ссылка #{component}
относится к компоненту current , где вычисляется выражение EL, и это работает только внутри любого из атрибутов самого компонента. Все, что вы хотите, также может быть достигнуто следующим образом:
var input = document.getElementById('#{emailAddress.clientId}');
с (обратите внимание на binding
на представление, вы должны абсолютно не привязать его к bean-компоненту)
<h:inputText binding="#{emailAddress}" />
, но это довольно уродливо. Лучше используйте следующий подход, в котором вы передаете сгенерированный элемент HTML DOM в качестве ссылки JavaScript this
на функцию
<h:inputText onclick="show(this)" />
с помощью
function show(input) {
alert(input.value);
}
Если вы используете jQuery, вы можете сделать еще один шаг, абстрагируя их, используя класс стиля в качестве интерфейса маркера
<h:inputText styleClass="someMarkerClass" />
с
$(document).on("click", ".someMarkerClass", function() {
var $input = $(this);
alert($input.val());
});
Идентификатор динамически генерируется, поэтому вы должны определять имена всех родительских элементов, чтобы избежать идентификаторов j_id123.
Обратите внимание, что если вы используете jQuery для выбора элемента, то вам следует использовать двойную косую черту перед двоеточием:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
вместо:
jQuery("my-form-id:my-text-input-block:my-input-id")
В случае Richfaces вы можете использовать выражение el на странице jsf:
#{rich:element('native-jsf-input-id')}
, чтобы выбрать элемент javascript , например:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
Вы можете просмотреть исходный код HTML при его создании и посмотреть, на что установлен идентификатор, поэтому вы можете использовать его в своем JavaScript. Поскольку он находится в форме, он, вероятно, добавляет к нему идентификатор формы.