Вы также можете попробовать idxmax
:
In [5]: df = pandas.DataFrame(np.random.randn(10,3),columns=['A','B','C'])
In [6]: df
Out[6]:
A B C
0 2.001289 0.482561 1.579985
1 -0.991646 -0.387835 1.320236
2 0.143826 -1.096889 1.486508
3 -0.193056 -0.499020 1.536540
4 -2.083647 -3.074591 0.175772
5 -0.186138 -1.949731 0.287432
6 -0.480790 -1.771560 -0.930234
7 0.227383 -0.278253 2.102004
8 -0.002592 1.434192 -1.624915
9 0.404911 -2.167599 -0.452900
In [7]: df.idxmax()
Out[7]:
A 0
B 8
C 7
, например
In [8]: df.loc[df['A'].idxmax()]
Out[8]:
A 2.001289
B 0.482561
C 1.579985
Хорошо, что это не будет поддерживаться на C # 4. Существует фундаментальная проблема:
List<Giraffe> giraffes = new List<Giraffe>();
giraffes.Add(new Giraffe());
List<Animal> animals = giraffes;
animals.Add(new Lion()); // Aargh!
Хранить жирафов в безопасности: просто скажите «нет» небезопасной дисперсии.
Массив версия работает, потому что массивы do поддерживают отклонение ссылочного типа с проверкой времени выполнения. Пункт дженериков состоит в том, чтобы обеспечить безопасность типа compile-time .
В C # 4 будет поддерживаться универсальная дисперсия safe , но только для интерфейсов и делегатов. Таким образом, вы сможете:
Func<string> stringFactory = () => "always return this string";
Func<object> objectFactory = stringFactory; // Safe, allowed in C# 4
Func<out T>
covariant в T
, потому что T
используется только в выходной позиции. Сравните это с Action<in T>
, который контравариантен в T
, потому что T
используется только там, где находится входное положение, делая это безопасным:
Action<object> objectAction = x => Console.WriteLine(x.GetHashCode());
Action<string> stringAction = objectAction; // Safe, allowed in C# 4
IEnumerable<out T>
также является ковариантным, делая это исправить в C # 4, как указано другими:
IEnumerable<Animal> animals = new List<Giraffe>();
// Can't add a Lion to animals, as `IEnumerable<out T>` is a read-only interface.
Что касается работы с этим в вашей ситуации на C # 2, вам нужно поддерживать список one или Вы были бы счастливы создать новый список? Если это приемлемо, List<T>.ConvertAll
является вашим другом.
Ковариация / контравариантность не могут поддерживаться в изменчивых коллекциях, о которых упоминали другие, потому что невозможно гарантировать безопасность типов во время компиляции; однако, можно сделать быстрое одностороннее преобразование в C # 3.5, если это то, что вы ищете:
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes.Cast<Animal>().ToList();
Конечно, это не одно и то же, это не ковариантность - вы фактически создаете еще один список, но это «обходной путь», так сказать.
В .NET 2.0 вы можете использовать ковариацию массива для упрощения кода:
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = new List<Animal>(giraffes.ToArray());
Но имейте в виду, что вы на самом деле создаете две новые коллекции здесь.
IList<T>
нет метода Cast
, это метод расширения Enumerable<T>.Cast<T2>
, который принимает IEnumerable<T>
и явно передает каждый элемент в T2
, а затем возвращает его (как IEnumerable<T2>
, а не IList<T2>
). Это не имеет никакого отношения к IList<T>
вообще, за исключением того факта, что IList<T>
наследуется от IEnumerable<T>
и, таким образом, поддерживает методы расширения Enumerable<T>
. Ковариантности там нет.
– Aaronaught
22 July 2014 в 15:17
В терминах List<T>
, боюсь, вам не повезло. Тем не менее, .NET 4.0 / C # 4.0 добавляет поддержку ковариантных / контравариантных интерфейсов. В частности, IEnumerable<T>
теперь определяется как IEnumerable<out T>
, что означает, что параметр типа теперь ковариант .
Это означает, что вы можете что-то сделать например, в C # 4.0 ...
// implicit casting
IEnumerable<Animal> animalsList = new List<Giraffe>();
// explicit casting
IEnumerable<Animal> animalsList2 = (IEnumerable<Animal>) new List<Giraffe>();
Примечание. Типы массивов также были ковариантными (по крайней мере с .NET 1.1).
Я считаю, что стыдно, что поддержка дисперсии не был добавлен для IList<T>
и других подобных общих интерфейсов (или общих классов), но, по крайней мере, у нас есть что-то.
Он будет работать в C # 4 для IEnumerable<T>
, поэтому вы можете сделать:
IEnumerable<Animal> animals = new List<Giraffe>();
Однако List<T>
не является ковариационной проекцией, поэтому вы не можете назначать списки, как вы это делали выше так как вы могли бы сделать это:
List<Animal> animals = new List<Giraffe>();
animals.Add(new Monkey());
Это явно недействительно.
Func<string>
-Func<object>
и факту, чтоT
контравариантно вAction
. СледующийAction<object> = Action<string>
не будет работать в C # 4. – Stan R. 9 January 2010 в 17:17animals.Add(new Lion()); // Aargh!
? Если вы можете использоватьLion
и использовать его какAnimal
, и если вы используете все элементы вanimals
какAnimal
s, то в чем проблема? – Jeff 12 April 2017 в 20:04animals
фактически i> относится кList<Giraffe>
. Таким образом, вы получите ссылкуLion
вList<Giraffe>
, что плохо ... – Jon Skeet 12 April 2017 в 20:32