[Сначала создайте новый столбец, чтобы объединить оба столбца.
df1["new_column"] = df1.bla2.fillna(df1.bla1);
Затем объедините оба кадра и удалите дополнительные созданные столбцы.
df3 = pd.merge(df1, df2, how="inner", left_on="new_column", right_on="bla").drop(["new_column", "bla"], axis=1)
Из-за проблем, повышенных в этом потоке, я отправляю другой ответ, показывающий, что происходит, если Вы понимаете его превратно... главным образом, что Вы не можете использовать массив GetHashCode()
; корректное поведение состоит в том, что никакие предупреждения не печатаются при выполнении его... переключают комментарии для фиксации его:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
static void Main()
{
// first and second are logically equivalent
SimpleTableRow<int> first = new SimpleTableRow<int>(1, 2, 3, 4, 5, 6),
second = new SimpleTableRow<int>(1, 2, 3, 4, 5, 6);
if (first.Equals(second) && first.GetHashCode() != second.GetHashCode())
{ // proven Equals, but GetHashCode() disagrees
Console.WriteLine("We have a problem");
}
HashSet<SimpleTableRow<int>> set = new HashSet<SimpleTableRow<int>>();
set.Add(first);
set.Add(second);
// which confuses anything that uses hash algorithms
if (set.Count != 1) Console.WriteLine("Yup, very bad indeed");
}
}
class SimpleTableRow<T> : IEquatable<SimpleTableRow<T>>
{
public SimpleTableRow(int id, params T[] values) {
this.Id = id;
this.Values = values;
}
public int Id { get; private set; }
public T[] Values { get; private set; }
public override int GetHashCode() // wrong
{
return Id.GetHashCode() ^ Values.GetHashCode();
}
/*
public override int GetHashCode() // right
{
int hash = Id;
if (Values != null)
{
hash = (hash * 17) + Values.Length;
foreach (T t in Values)
{
hash *= 17;
if (t != null) hash = hash + t.GetHashCode();
}
}
return hash;
}
*/
public override bool Equals(object obj)
{
return Equals(obj as SimpleTableRow<T>);
}
public bool Equals(SimpleTableRow<T> other)
{
// Check for null
if (ReferenceEquals(other, null))
return false;
// Check for same reference
if (ReferenceEquals(this, other))
return true;
// Check for same Id and same Values
return Id == other.Id && Values.SequenceEqual(other.Values);
}
}
FWIW, очень опасно использовать содержание Значений в Вашем хэш-коде. Необходимо только сделать это, если можно гарантировать, что это никогда не будет изменяться. Однако, так как это представлено, я не думаю, гарантируя, что это возможно. Хэш-код объекта никогда не должен изменяться. Иначе это теряет свое значение как ключ в Хеш-таблице или Словаре. Рассмотрите дефицитную ошибку использования объекта как ключ в Хеш-таблице, ее изменениях хэш-кода из-за внешнего влияния, и Вы больше не можете находить его в Хеш-таблице!
Так как хэш-код является своего рода ключевым для того, чтобы хранить объект (lllike в хеш-таблице), я использовал бы просто идентификатор. GetHashCode ()
Как насчет чего-то как:
public override int GetHashCode()
{
int hash = Id;
if (Values != null)
{
hash = (hash * 17) + Values.Length;
foreach (T t in Values)
{
hash *= 17;
if (t != null) hash = hash + t.GetHashCode();
}
}
return hash;
}
Это должно быть совместимо с SequenceEqual
, вместо того, чтобы делать ссылочное сравнение на массиве.
public override int GetHashCode() {
return Id.GetHashCode() ^ Values.GetHashCode();
}
<час> существует несколько положительных сторон в комментариях и других ответах. OP должен рассмотреть, использовались ли Значения в качестве части "ключа", если объект использовался в качестве ключа в словаре. Если так, тогда они должны быть частью хэш-кода, иначе, нет.
, С другой стороны, я не уверен, почему метод GetHashCode должен зеркально отразить SequenceEqual. Это предназначено, чтобы вычислить индекс в хэш-таблицу, не быть полным детерминантом равенства. Если существует много коллизий хэш-таблицы с помощью алгоритма выше, и если они отличаются по последовательности Значений, то алгоритм должен быть выбран, который принимает последовательность во внимание. Если последовательность действительно не имеет значения, экономит время и не принимает его во внимание.
Я сделал бы это этот путь:
long result = Id.GetHashCode();
foreach(T val in Values)
result ^= val.GetHashCode();
return result;
При условии, что идентификатор и Значения никогда не будут изменяться, и Значения не являются нулевыми...
public override int GetHashCode()
{
return Id ^ Values.GetHashCode();
}
Примечание, что Ваш класс не неизменен, так как любой может изменить содержание Значений, потому что это - массив. Учитывая, что, я не попытался бы генерировать хэш-код с помощью его содержания.