Сначала set_index
и проверьте все пропущенные значения с подсчетом по sum
, а затем объедините count
с sum
:
df = tdf.set_index('indicator').isnull().sum(axis=1).groupby(level=0).agg(['count','sum'])
print (df)
count sum
indicator
A 2 3
B 2 7
C 1 0
Деталь [1113 ]:
print (tdf.set_index('indicator').isnull().sum(axis=1))
indicator
A 2
A 1
B 4
B 3
C 0
dtype: int64
Другое решение - использовать функцию с GroupBy.apply
:
def func(x):
a = len(x)
b = x.isnull().values.sum()
return pd.Series([a,b],index=['indicator count','nulls count'])
df = tdf.set_index('indicator').groupby('indicator').apply(func)
print (df)
indicator count nulls count
indicator
A 2 3
B 2 7
C 1 0
В C++ структуры и классы идентичны за исключением общественности/частности по умолчанию их участников. (Это значение по умолчанию легко, и обычно, переопределено.)
Однако большинство программистов думает о структуре как об "объекте данных" и классе как "интерактивный объект". Это не плохая вещь; и на самом деле должен быть использован в своих интересах. Если что-то - просто неодушевленная глыба данных (даже, возможно, если они имеют несколько методов инспектора), используйте структуру для них; это сэкономит немного усилий, когда программист попытается видеть то, для чего это.
Структуры прекрасны, пока они сохранены маленькими. Как Вы, вероятно, знаете, они выделяются на стеке (не "куча"), таким образом, необходимо наблюдать размер. Они могут пригодиться для небольших структур данных как Точка, Размер, и т.д. Класс обычно является лучшим выбором хотя, будучи ссылочным типом и так далее.
Нет ничего неправильно с использованием структур по сути, но если Вам нужны они, необходимо спросить что случилось с анализом. Рассмотрите, например, класс Точки выше: это дает некоторое небольшое улучшение удобочитаемости, так как можно всегда использовать
Point foo;
//...
foo.x = bar;
вместо, скажем, наличия двух массивов элемента как в
#define X 0
#define Y 1
//...
foo[X] = bar;
Но классы предназначены для сокрытия деталей позади контракта. Если Ваша Точка находится в некотором нормализованном пространстве, значения могут расположиться в полуоткрытом интервале [0.0.. 1.0); если это - экран, они могут расположиться в [0.. 1023]. Если Вы используете структуру вместо средств доступа, как Вы помешаете кому-то присваиваться foo.x = 1023
когда x
должен быть везде < 1.0
?
Единственная причина программисты на C++ использовали структуры для Точек, состоит в том, что назад в рассвет времени---20 лет назад, то, когда C++ был новым встраиванием---, не было обработано очень хорошо, так, чтобы foo.setX(1023)
на самом деле взял больше инструкций, чем foo.x = 1023
. Это больше не верно.
Посмотрите эти подобные вопросы:
Когда необходимо использовать класс по сравнению со структурой в C++?
Каковы различия между структурой и классом в C++
плюс:
По словам Stroustrup на языке программирования на C++:
Которые разрабатывают Вас, использование зависит от обстоятельств и вкуса. Я обычно предпочитаю использовать
struct
для классов, которые имеют всю общественность данных. Я думаю о таких классах как "не совсем надлежащие типы, просто структуры данных".
Официально, в C++ структура является классом с видимостью его членского набора общественности по умолчанию. По традиции структуры привыкли к набору группы гомогенных данных, которые не имеют никаких конкретных причин того, чтобы быть полученными доступ определенными методами. Общедоступная видимость его участников делает структуры предпочтенными для классификации для реализации занятий по политике и метафункций.
Если существует потребность в инварианте, сделайте это классом. Иначе структура в порядке.
Большинство ответов, кажется, выступает за структуру как что-то, чтобы быть приемлемым и полезным, пока она не имеет поведения (т.е. методы). Это кажется достаточно справедливым.
Однако Вы никогда не можете быть уверены, что Ваш объект не развивается во что-то, чему, возможно, понадобятся поведение и следовательно некоторое управление его элементами данных. Если Вам повезло, что Вы управляете всеми пользователями своей структуры, можно пробежаться через все использование всех элементов данных. Но что, если у Вас нет доступа ко всем пользователям?
Структура, как используется в C или C++ и структуре, используемой в C# (или любой язык .NET), является такими различными животными, что у них, вероятно, даже не должно быть того же имени... Примерно любое обобщение о структурах на одном языке может легко быть ложью, или верный по абсолютно несвязанной причине, в другом.
Я регулярно использую структуры - главным образом для данных, полученных от сетевых или аппаратных средств. Они обычно переносятся в класс для использования высокоуровневыми частями программы.
Мое эмпирическое правило является структурой, всегда чистые данные, за исключением конструктора. Что-либо еще - класс.
Структура является по существу образцовым классом, но с другим синтаксисом.
public struct Point {
int x;
int y;
}
логически то же как:
public class Point {
private int x;
private int y;
public void setX(int x) { this.x=x; }
public int getX(); { return x; }
public void setY(int y) { this.y=y; }
public int getY(); { return y; }
}
Оба - изменяемая модель, которая содержит пару целочисленных значений, названных X и Y. Таким образом, я сказал бы, что это - ориентированная конструкция доступного объекта.
Вопрос легок. Если class
действительно имеет инварианты для гарантии, Вы никогда не должны делать участников, ограничивающих инвариантную общественность.
Если Ваш struct
просто агрегат различных объектов и не имеет инварианта для содержания, Вы действительно свободны и поощряетесь поместить его участников public
. Это - путь std::pair<T, U>
в C++ делает это.
Простой пример: Полагайте, что у Вас есть a Point
класс, чей x and y
участники должны всегда быть >= 0
. Можно сделать инвариантное утверждение
/* x >= 0 && y >= 0 for this classes' objects. */
Если Вы теперь обнародовали тех участников, клиенты могли бы просто изменить X и Y, и Ваш инвариант мог повредиться легко. Если участникам, однако, разрешают содержать все возможные значения, соответствующие их собственным инвариантам соответственно, Вы могли, конечно, просто обнародовать тех участников: Вы не добавили бы защиты к ним так или иначе.
Технически, структура является классом с видимостью по умолчанию общественности (реальный класс имеет видимость по умолчанию частных).
Существует больше широко использующегося различия.
Структура является обычно просто набором данных, чтобы быть исследованной и обработанной другим кодом.
Класс обычно является большим количеством вещи, обеспечивая своего рода контроль над его данными, и с поведением, указанным присоединенными функциями.
Как правило, классы более полезны, но время от времени существует использование для чего-то как структура C, и полезно иметь письменное различие для показа его.
В C++, различии между структурой и классом видимость по умолчанию его содержания (т.е. общественность для структуры, и частный за класс). Я предполагаю, что это различие должно было сохранить совместимость C.
Но семантически, я предполагаю, что это подвергается интерпретации.
В структуре все общедоступно (по умолчанию), означая, что пользователь может изменить каждое значение данных, как желаемый, и тем не менее структура остается доступным объектом. Пример структуры:
struct CPoint
{
int x ;
int y ;
CPoint() : x(0), y(0) {}
int getDistanceFromOrigin() const
{
return std::sqrt(x * x + y * y) ;
}
} ;
inline CPoint operator + (const CPoint & lhs, const CPoint & rhs)
{
CPoint r(lhs) ;
r.x += rhs.x ;
r.y += rhs.y ;
return r ;
}
Можно изменить x значение CPoint, и это все еще остается допустимым CPoint.
Обратите внимание, что, в отличие от некоторых верят, структура C++ может (и если) имеют конструкторов, методы и не являющиеся членом функции, присоединенные к ее интерфейсу, как показано выше.
В классе все является частным (по умолчанию), означая, что пользователь может изменить данные только через четко определенный интерфейс, потому что класс должен сохранить свои внутренности допустимыми. Пример класса:
class CString
{
public :
CString(const char * p) { /* etc. */ } ;
CString(const CString & p) { /* etc. */ } ;
const char * getString() const { return this->m_pString ; }
size_t getSize() const { return this->m_iSize ; }
void copy { /* code for string copy */ }
void concat { /* code for string concatenation */ }
private :
size_t m_iSize ;
char * m_pString ;
} ;
inline CString operator + (const CString & lhs, const CString & rhs)
{
CString r(lhs) ;
r.concat(rhs) ;
return r ;
}
Вы видите, что при вызове concat, оба, указатель мог нуждаться в перераспределении (для увеличения его размера), и размер строки должен быть обновлен автоматически. Вы не можете позволить пользователю изменить строку вручную и забыть обновлять размер.
Так, класс должен защитить свое внутреннее, и быть уверен, что все будет правильно обновлено при необходимости.
Для меня, различия между структурой и классом зависимости между агрегированными данными.
Если каждая часть данных независима от всего другие, то, возможно, необходимо рассмотреть структуру (т.е. класс с общедоступным элементом данных).
В противном случае или если в сомнении, используйте класс.
Теперь, конечно, в C#, структура и класс являются двумя другими типами объектов (т.е. оцените типы за структуры и типы, на которые ссылаются, для классов). Но это вне этой темы, я предполагаю.
В C#, например, я использую структуры для некоторых простых better-left-as-values типов данных:
public struct Point
{
int X;
int Y;
}
и для любого P/Invoke к библиотекам, где аргументами являются структуры, необходимо будет использовать их наверняка.
Они принадлежат общего дизайна приложения? Конечно, они делают, используют структуру, когда имеет смысл делать так. Точно так же, как Вы использовали бы перечисление с битовыми флагами, когда имеет смысл делать так вместо того, чтобы обратиться к некоторому сложному строковому парсингу для хранения общей стоимости.
Да, они делают. Они имеют отличающийся семантический, чем классы. Структуру обычно рассматривают и рассматривают как тип значения, в то время как класс обычно рассматривают и рассматривают как ссылочный тип. Различием не является столько же pronunciated в каждый день, программируя; однако, это - imprtant различие когда дело доходит до вещей как маршалинг, взаимодействующий с COM и раздавание экземпляров.
Не будьте скрывающимся зилотом. Если Ваш добраться/методы установки действительно только просто копируют дословно значение на/от скрытое, частное поле, Вы ничего не получили по общедоступному участнику и только усложняете излишне Ваш класс (и, в зависимости от аналитики компилятора, замедлите его использование немного).
Существует случай для того, чтобы не предоставлять прямой доступ, когда Ваши методы установщика делают некоторую проверку, скопируйте данные где-то в другом месте, обработайте их немного прежде, чем сохранить их и т.д. То же в случае методов считывания, которые на самом деле вычисляют значение, которое они возвращают из нескольких внутренних источников и скрывают способ, которым оно произошло (я верю Bertrand Meyer, говорит немного об этом в его книге),
Или если разрешение пользователей Вашего класса непосредственно изменить такое значение имело бы непреднамеренные побочные эффекты или повреждает предположение, которое некоторые Ваши членские классы имеют о значениях. На тех ситуациях, любой ценой, действительно скрывают Ваши значения.
Например, для простого класса "Точки", это только содержит пару координат и цвета и методов, чтобы "Вывести его на печать" и "Скрыть" его на экране, я не видел бы никакой смысл в не разрешении пользователю непосредственно установить значения для его полей.