Вам просто нужна функция argmax()
(, теперь называемая функцией idxmax
). Это просто:
>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
A B C
0 1.232853 -1.979459 -0.573626
1 0.140767 0.394940 1.068890
2 0.742023 1.343977 -0.579745
3 2.125299 -0.649328 -0.211692
4 -0.187253 1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1
Эта функция была обновлена до имени idxmax
в API Pandas, хотя с Pandas 0.16, argmax
все еще существует и выполняет ту же функцию (хотя, похоже, запускается больше медленнее, чем idxmax
).
Вы также можете просто использовать numpy.argmax
, например numpy.argmax(df['A'])
- он обеспечивает то же самое, что и любая из двух функций pandas
, и появляется по крайней мере как idxmax
Ранее (как отмечалось в комментариях) оказалось, что argmax
будет существовать как отдельная функция, которая обеспечивала целочисленную позицию в пределах индекс расположения строки максимального элемента. Например, если у вас есть строковые значения в качестве ярлыков индексов, например, строки 'a' through 'e', вы можете знать, что max встречается в строке 4 (а не в строке 'd'). Однако в pandas 0.16 все перечисленные выше методы предоставляют только метку из Index
для рассматриваемой строки, и если вы хотите, чтобы целое число позиции этой метки внутри Index
, вы придется вручную (это может быть сложно теперь, когда допустимы дубликаты строк).
В общем, я думаю, что переход к idxmax
-подобному поведению для всех трех подходов (argmax
, который все еще существует, idxmax
и numpy.argmax
) является плохим, так как очень часто требуется, чтобы позиционное целочисленное местоположение было максимально, возможно, даже более распространенным, чем желание метки это позиционное расположение в пределах некоторого индекса, особенно в приложениях, где одинаковые ярлыки строк являются общими.
Например, рассмотрите эту игрушку DataFrame
с двойной меткой строки:
In [19]: dfrm
Out[19]:
A B C
a 0.143693 0.653810 0.586007
b 0.623582 0.312903 0.919076
c 0.165438 0.889809 0.000967
d 0.308245 0.787776 0.571195
e 0.870068 0.935626 0.606911
f 0.037602 0.855193 0.728495
g 0.605366 0.338105 0.696460
h 0.000000 0.090814 0.963927
i 0.688343 0.188468 0.352213
i 0.879000 0.105039 0.900260
In [20]: dfrm['A'].idxmax()
Out[20]: 'i'
In [21]: dfrm.ix[dfrm['A'].idxmax()]
Out[21]:
A B C
i 0.688343 0.188468 0.352213
i 0.879000 0.105039 0.900260
So здесь наивное использование idxmax
недостаточно, тогда как старая форма argmax
правильно обеспечит расположение позиционного максимального ряда (в этом случае позиция 9).
Это ровно один из тех неприятных видов склонности к ошибкам поведения на динамически типизированных языках, что делает такие вещи такими неудачными и стоит победить мертвую лошадь. Если вы пишете системный код, и ваша система внезапно используется на некоторых наборах данных, которые не были очищены должным образом перед присоединением, очень легко получить дубликаты строк, особенно строковые метки, такие как идентификатор CUSIP или SEDOL для финансовых активов. Вы не можете легко использовать систему типов, чтобы помочь вам, и вы не сможете обеспечить уникальность индекса, не запуская неожиданно отсутствующих данных.
Итак, вы остались в надежде, что ваши юнит-тесты охватывают все (они этого не сделали или, скорее всего, никто не написал никаких тестов) - иначе (скорее всего) вы просто останетесь ждать, чтобы увидеть если вы случайно попали в эту ошибку во время выполнения, и в этом случае вам, вероятно, придется отказаться от работы на многие часы из базы данных, на которую вы выводили результаты, ударить головой о стену в IPython, пытаясь вручную воспроизвести проблему, наконец что idxmax
может только сообщать метку максимальной строки, а затем разочаровываться в том, что никакая стандартная функция автоматически не получает позиции максимальной строки для вас, самостоятельно записывая баггирование, редактируя код и молясь, чтобы вы снова не сталкивались с проблемой.
Это должно работать:
IQueryable parentQuery = context.Parent.Select(p => new { Parent = p, ChildCount = p.Childs.Count() });
EDIT
Если вы определяете:
public class ParentModel
{
public Task Parent { get; set; }
public int ChildCount { get; set; }
}
, вы можете использовать
IQueryable parentQuery = context.Parent.Select(p => new ParentModel { Parent = p, ChildCount = p.Childs.Count() });
EDIT
Вы также можете сделать:
var parentQuery = context.Parent.Select(p => new { Parent = p, ChildCount = p.Childs.Count() }).ToList();
parentQuery.ForEach(p => p.Parent.ChildCount = p.ChildCount);
var result = return parentQuery.Select(p => p.Parent);
Короткие и у вас есть ваша собственность.