Использовать:
#if necessary replace string NaN to missing values
F1 = F1.replace('NaN', np.nan)
F2 = F2.replace('NaN', np.nan)
Для каждого столбца удалить дубликаты по DataFrame.drop_duplicates
, пропустить valeus по DataFrame.dropna
и создать индекс по столбцу id
DataFrame.set_index
:
s1 = F2.drop_duplicates('id1').dropna(subset=['id1']).set_index('id1')['Description']
s2 = F2.drop_duplicates('id2').dropna(subset=['id2']).set_index('id2')['Description']
Затем используйте Series.map
по столбцам из F1
с Series.combine_first
: [1117 ]
F1['Description'] = F1['id1'].map(s1).combine_first(F1['id2'].map(s2))
print (F1)
id1 id2 Description
0 x22 NaN California
1 x13 223 LA
2 NaN 788 NY
3 x421 NaN Munich
Я не очень уверен в том, что Вы пытаетесь выполнить, но возможно SerialPort. Событие DataReceived является лучшим решением?
Если Вы являетесь уже опытными с использованием потоков, я не вижу точку в использовании BackgroundWorker. Это разработано для людей, которые не понимают потоков во-первых.
Кроме того, мне не нравится идея прервать поток. Это чувствует себя опасным, и для многопоточных приложений больше не нужно принятие риска.
Я не думаю уничтожение поддержек BackgroundWorker потока. Отмена операции должна быть сделана в методе, который выполняет задание. В Вашем случае я думаю, что регулярный поток будет наилучшим вариантом.
The process should not become a zombie, since the BackgroundWorker thread is marked as "background" and should end when the UI is closed.
Я собрал один, который (я думаю) выполняет свою работу. Пожалуйста, дайте мне знать, если я отключился. Вот простой пример того, как это работает.
var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};
backgroundWorker.DoWork += (sender, args) =>
{
var thisWorker = sender as BackgroundWorker;
var _child = new Thread(() =>
{
//..Do Some Code
});
_child .Start();
while (_child.IsAlive)
{
if (thisWorker.CancellationPending)
{
_child.Abort();
args.Cancel = true;
}
Thread.SpinWait(1);
}
};
backgroundWorker.RunWorkerAsync(parameter);
//..Do Something...
backgroundWorker.CancelAsync();
Поскольку фоновый рабочий процесс является частью пула потоков, мы не хотим его прерывать. Но мы можем запустить поток внутри, в котором мы можем позволить произойти прерыванию. Затем backgroundWorker в основном выполняется до тех пор, пока дочерний поток не будет завершен, или пока мы не дадим ему сигнал убить процесс. Затем фоновый рабочий поток может вернуться в пул чтения. Обычно я заключаю это во вспомогательный класс и передаю метод делегата, который я хочу, чтобы фоновый поток запускался, переданный в качестве параметра, и запускал его в дочернем потоке.
Пожалуйста, дайте мне знать, если я бьюсь головой о стену, но, похоже, все работает нормально ... Но проблема с потоками не в этом ... различные результаты, которые вы можете получить, запустив его в разное время.