Более быстрые результаты могут быть достигнуты с помощью numpy.where .
Например, при настройке unubtu -
In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]:
A B C D
0 foo one 0 0
2 foo two 2 4
4 foo two 4 8
6 foo one 6 12
7 foo three 7 14
Сроки сравнения:
In [68]: %timeit df.iloc[np.where(df.A.values=='foo')] # fastest
1000 loops, best of 3: 380 µs per loop
In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop
In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop
In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop
In [74]: %timeit df.query('(A=="foo")') # slowest
1000 loops, best of 3: 1.71 ms per loop
Насколько я знаю, выполняю итерации и инстанцирую, единственный способ сделать это. Что-то как (для справки потенциала других, так как я уверен, что Вы знаете, как сделать это):
List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<String>(oldList.size())
for (Integer myInt : oldList) {
newList.add(String.valueOf(myInt));
}
Это - такая основная вещь сделать, я не пользовался бы внешней библиотекой (она вызовет зависимость в Вашем проекте, в котором Вы, вероятно, не нуждаетесь).
у Нас есть класс статических методов, конкретно обработанных, чтобы делать подобные работы. Поскольку код для этого так прост, мы позволяем Горячей точке сделать оптимизацию для нас. Это, кажется, тема в моем коде недавно: запишите очень простой (простой) код и позвольте Горячей точке сделать свое волшебство. У нас редко есть проблемы производительности вокруг кода как это - когда новая версия виртуальной машины приходит, Вы извлекаете всю дополнительную пользу скорости и т.д.
так, как я люблю Джакартские наборы, они не поддерживают Дженериков и используют 1.4 в качестве жидкокристаллического дисплея. Я опасаюсь Google Collections, потому что они перечислены как уровень поддержки Alpha!
Только для забавы, решение с помощью jsr166y платформы соединения ветвления, которая должна в JDK7.
import java.util.concurrent.forkjoin.*;
private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
ParallelArray.create(ints.size(), Integer.class, executor)
.withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
return String.valueOf(i);
}})
.all()
.asList();
(Правовая оговорка: Не скомпилированный. Спецификация не завершена. И т.д.)
Вряд ли, чтобы быть в JDK7 немного вывода типа и синтаксического сахара для создания этого, withMapping называют менее подробными:
.withMapping(#(Integer i) String.valueOf(i))
Вы не можете избежать "упаковки наверху"; поддельные универсальные контейнеры Java могут только хранить Объекты, таким образом, Ваш ints должен быть упакован в Целые числа. В принципе это могло избежать удрученного от Объекта до Целого числа (так как это бессмысленно, потому что Объект достаточно хорош и для String.valueOf и для Object.toString), но я не знаю, достаточно ли компилятор умен сделать это. Преобразование из Строки для Возражения должно быть более или менее не, таким образом, я был бы лишен желания для волнения о том.
Ответ для экспертов только:
List<Integer> ints = ...;
String all = new ArrayList<Integer>(ints).toString();
String[] split = all.substring(1, all.length()-1).split(", ");
List<String> strs = Arrays.asList(split);
@Jonathan: Я мог ошибиться, но я полагаю, что String.valueOf () в этом случае назовет String.valueOf (Объектной) функцией вместо того, чтобы быть упакованным к String.valueOf (интервал). String.valueOf (Объект) просто возвращает "пустой указатель", если это является пустым или называет Object.toString (), если непустой указатель, который не должен включать упаковку (хотя, очевидно, инстанцируя новых строковых объектов включен).
Я думаю с помощью Object.toString () для любой цели кроме отладки, вероятно, действительно плохая идея, даже при том, что в этом случае эти два функционально эквивалентны (предположение, что список не имеет никакого, аннулирует). Разработчики свободны изменить поведение любого toString () метод без любого предупреждения, включая toString () методы любых классов в стандартной библиотеке.
даже не волнуются о проблемах производительности, вызванных процессом упаковки/распаковывания. Если производительность очень важна, просто используйте массив. Если это действительно очень важно, не используйте Java. Попытка перехитрить JVM только приведет к страданию.
Не базовый Java, и не универсальный-ified, но популярная Джакартская библиотека наборов свободного городского населения имеет некоторые полезные абстракции для этого вида задачи. А именно, взгляните на собрать методы по телефону
Что-то, чтобы рассмотреть, используете ли Вы уже наборы свободного городского населения в своем проекте.
Вместо того, чтобы использовать String.valueOf я использовал бы .toString (); это избегает части автоматической упаковки, описанной @johnathan.holland
, javadoc говорит, что valueOf возвращает то же самое как Integer.toString ().
List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());
for (Integer myInt : oldList) {
newList.add(myInt.toString());
}
Источник для String.valueOf показывает это:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Не то, чтобы это имеет значение очень, но я использовал бы toString.
То, что Вы делаете, прекрасно, но если Вы чувствуете потребность к 'Java-it-up', Вы могли бы использовать , Преобразователь и эти собирает метод от Apache палата общин , например:
public class IntegerToStringTransformer implements Transformer<Integer, String> {
public String transform(final Integer i) {
return (i == null ? null : i.toString());
}
}
.. и затем..
CollectionUtils.collect(
collectionOfIntegers,
new IntegerToStringTransformer(),
newCollectionOfStrings);
Людям, обеспокоенным "упаковкой" в ответе jsight: нет ни одного. String.valueOf(Object)
используется здесь, и никакое распаковывание к int
никогда не выполняется.
, Используете ли Вы Integer.toString()
или String.valueOf(Object)
, зависит от того, как Вы хотите обработать возможные пустые указатели. Вы хотите выдать исключение (вероятно), или иметь "пустые" Строки в Вашем списке (возможно). Если первый, Вы хотите бросить NullPointerException
или некоторый другой тип?
кроме того, один маленький дефект в ответе jsight: List
интерфейс, Вы не можете использовать новый оператор на нем. Я, вероятно, использовал бы java.util.ArrayList
в этом случае, тем более, что мы знаем впереди, какой длины список, вероятно, будет.
Используя Коллекции Google из Guava-Project , вы можете использовать метод transform
в классе Lists
import com.google.common.collect.Lists;
import com.google.common.base.Functions
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = Lists.transform(integers, Functions.toStringFunction());
Список
, возвращенный преобразованием
, является представлением в списке поддержки - преобразование будет применяться при каждом доступе к преобразованному списку.
Имейте в виду, что Functions.toStringFunction ()
вызовет исключение NullPointerException
при применении к null, поэтому используйте его только в том случае, если вы уверены, что ваш список не будет содержать null.
Lambdaj позволяет сделать это очень простым и понятным способом. Например, предположим, что у вас есть список целых чисел и вы хотите преобразовать их в соответствующее строковое представление, вы можете написать что-то вроде этого:
List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
public String convert(Integer i) { return Integer.toString(i); }
}
Lambdaj применяет функцию преобразования только во время итерации результата.