Метод расширения GetHashCode

Для меня ваше решение работает, возможно, необходимо заменить пустые значения на NaN с:

df_stats = df_path.replace('',np.nan).groupby('id', as_index=False).first()
print (df_stats)
       id  Index  Height  Speed
0  100007      0    54.0    8.3
1  100014      5    44.0    NaN
2  100035      4    39.0    5.6
12
задан 18 April 2009 в 16:34
поделиться

7 ответов

Это выглядит как надежный способ сделать это.

Мое единственное предложение - если вы действительно обеспокоены Что касается производительности, вы можете добавить общие версии для нескольких общих случаев (например, 1-4 аргумента). Таким образом, для этих объектов (которые, скорее всего, будут небольшими, составными объектами в стиле ключа), у вас не будет лишних затрат на создание массива для передачи в метод, цикл, любой бокс общих значений и т. Д. Синтаксис вызова будет точно таким же, но вы будете выполнять немного более оптимизированный код для этого случая. Конечно, я бы проверил некоторые тесты на это, прежде чем вы решите, стоит ли компромисс с обслуживанием.

Примерно так:

public static int GetHashCodeFromFields<T1,T2,T3,T4>(this object obj, T1 obj1, T2 obj2, T3 obj3, T4 obj4) {
    int hashCode = _seedPrimeNumber;
    if(obj1 != null)
        hashCode *= _fieldPrimeNumber + obj1.GetHashCode();
    if(obj2 != null)
        hashCode *= _fieldPrimeNumber + obj2.GetHashCode();
    if(obj3 != null)
        hashCode *= _fieldPrimeNumber + obj3.GetHashCode();
    if(obj4 != null)
        hashCode *= _fieldPrimeNumber + obj4.GetHashCode();
    return hashCode;
}
3
ответ дан 2 December 2019 в 23:08
поделиться

Я выгляжу очень хорошо для меня, у меня есть только одна проблема: это позор, что вы должны использовать object [] для передачи значений, поскольку это будет блокировать любые типы значений, которые вы отправляете в функцию. Я не думаю, что у вас есть большой выбор, если только вы не пойдете по пути создания некоторых общих перегрузок, как предлагали другие.

1
ответ дан 2 December 2019 в 23:08
поделиться

По общему принципу вы должны ограничить свой непроверенный настолько узко, насколько это возможно, хотя это не имеет большого значения здесь. Кроме того, выглядит хорошо.

0
ответ дан 2 December 2019 в 23:08
поделиться
public override int GetHashCode() {
    return this.GetHashCodeFromFields(field1, field2, field3, this);
}

(да, я очень педантичен, но это единственная проблема, которую я вижу)

0
ответ дан 2 December 2019 в 23:08
поделиться

More optimal:

  1. Create a code generator that uses reflection to look through your business object fields and creates a new partial class which overrides GetHashCode() (and Equals()).
  2. Run the code generator when your program starts up in debug mode, and if the code has changed, exit with a message to the developer to recompile.

The advantages of this are:

  • Using reflection you know which fields are value types or not, and hence whether they need null checks.
  • There are no overheads - no extra function calls, no list construction, etc. This is important if you are doing lots of dictionary lookups.
  • Long implementations (in classes with lots of fields) are hidden in partial classes, away from your important business code.

Disadvantages:

  • Overkill if you don't do lots of dictionary lookups/calls to GetHashCode().
0
ответ дан 2 December 2019 в 23:08
поделиться

Я должен отметить, что при реализации GetHashCode вы почти никогда не должны выполнять распределение (вот некоторые полезные blog сообщения об этом).

То, как работает params (создание нового массива на лету), означает, что это действительно не так) хорошее общее решение. Было бы лучше использовать вызов метода для каждого поля и поддерживать состояние хеш-функции как передаваемую им переменную (это упрощает использование лучших функций хеширования и лавинного преобразования).

0
ответ дан 2 December 2019 в 23:08
поделиться

Некоторое время назад я написал кое-что, что вы могли бы решить вашу проблему ... (И на самом деле, его, вероятно, можно было бы улучшить, включив семя, которое у вас есть ...)

В любом случае проект называется Essence ( http://essence.codeplex.com/ ), и он использует библиотеки System.Linq.Expression для генерации (на основе атрибутов) стандартных представлений Equals / GetHashCode / CompareTo / ToString, а также возможность создавать классы IEqualityComparer и IComparer на основе списка аргументов. (У меня также есть несколько дополнительных идей, но я хотел бы получить некоторые отзывы сообщества, прежде чем продолжать слишком много.)

(Это означает, что это почти так же быстро, как и рукописный текст - главное, где это не так, это CompareTo (); потому что Linq.Expressions не имеет понятия переменной в 3. 5, поэтому вам нужно дважды вызвать CompareTo () для базового объекта, если вы не найдете совпадения. Использование расширений DLR для Linq.Expressions решает эту проблему. Полагаю, я мог бы использовать emit il, но в то время я не был так вдохновлен.)

Это довольно простая идея, но я не видел ее раньше.

Дело в том, что я как бы потерял интерес к его полировке (что включало бы написание статьи для codeproject, документирование части кода и т.п.), но меня, возможно, убедили бы сделать это, если вы считаете, что это будет что-то интересное.

(На сайте codeplex нет загружаемого пакета; просто перейдите к источнику и возьмите его - о, он написан на f # (хотя весь тестовый код находится на C #), так как это было то, что мне было интересно изучать.)

Так или иначе,

3
ответ дан 2 December 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: