Как вставить массив NaN в массив numpy 2D

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

Я пытаюсь вставить произвольное количество строк значений NaN в 2D-массив в определенных местах. Я записываю некоторые данные с микроконтроллера в файл .csv и анализирую с помощью python.

Данные хранятся в 2D-массиве с 3 столбцами, подобном этому

 [(122.0, 1.0, -47.0) (123.0, 1.0, -47.0) (125.0, 1.0, -44.0) ..., 
(39.0, 1.0, -47.0) (40.0, 1.0, -45.0) (41.0, 1.0, -47.0)]
  

Первый столбец — это счетчик последовательности. То, что я пытаюсь сделать, это перебирать значения последовательности, diff текущий и предыдущий порядковый номер и вставлять столько строк с nan, сколько недостающих последовательностей.

В основном,

 [(122.0, 1.0, -47.0) (123.0, 1.0, -47.0) (125.0, 1.0, -44.0)]
  

стало бы

 [(122.0, 1.0, -47.0) (123.0, 1.0, -47.0) (nan, nan, nan) (125.0, 1.0, -44.0)]
  

Однако следующая реализация np.insert выдает ошибку

 while (i < len(list[1])):
     pid = list[i][0]
     newMissing = (pid - LastGoodId   255) % 256
     TotalMissing = TotalMissing   newMissing
     np.insert(list,i,np.zeros(newMissing,1)   np.nan)   
     i = i   newMissing
     list[i][0] = TotalMissing
     LastGoodId = pid 
  

—> 28 np.insert(список, i, np.zeros(newMissing,1) np.nan)
29 i = i newMissing
30 list[i][0] = TotalMissing

Ошибка типа: тип данных не понят

Есть идеи о том, как я могу это сделать?

Комментарии:

1. Всегда полезно включать сообщение об ошибке, которое вы получаете, когда говорите, что что-то не работает.

2. Извините, я забыл. Добавлено сейчас.

3. Отсортирован ли первый столбец? Что происходит, когда первый столбец переходит из 125.0 to 39.0 , должны ли мы рассматривать их как недостающие элементы между ними? Под отсутствующими элементами вы всегда подразумеваете в порядке возрастания?

4. Да, данные в первом столбце являются инкрементными и обтекают 8-битное переполнение (0 — 255), поэтому, если первый столбец переходит от 125 к 39, это означает, что 168 пакетов были потеряны.

5. Это важная информация. Пожалуйста, добавьте это в вопрос.

Ответ №1:

Из документа np.insert() :

 import numpy as np
a = np.arrray([(122.0, 1.0, -47.0), (123.0, 1.0, -47.0), (125.0, 1.0, -44.0)]))
np.insert(a, 2, np.nan, axis=0)
array([[ 122.,    1.,  -47.],
       [ 123.,    1.,  -47.],
       [  nan,   nan,   nan],
       [ 125.,    1.,  -44.]])
  

Комментарии:

1. Попробовал np.insert(a, 2, np.nan, axis=0) и получил следующее сообщение об ошибке: TypeError: expected a readable buffer object

Ответ №2:

Подход # 1

Мы можем использовать подход, основанный на инициализации, для обработки нескольких пробелов и пробелов любой длины —

 # Pre-processing step to create monotonically increasing array for first col
id_arr = np.zeros(arr.shape[0])
id_arr[np.flatnonzero(np.diff(arr[:,0])<0) 1] = 256
a0 = id_arr.cumsum()   arr[:,0]

range_arr = np.arange(a0[0],a0[-1] 1)
out = np.full((range_arr.shape[0],arr.shape[1]),np.nan)
out[np.in1d(range_arr,a0)] = arr
  

Пример запуска —

 In [233]: arr      # Input array
Out[233]: 
array([[ 122.,    1.,  -47.],
       [ 123.,    1.,  -47.],
       [ 126.,    1.,  -44.],
       [  39.,    1.,  -47.],
       [  40.,    1.,  -45.],
       [  41.,    1.,  -47.]])

In [234]: out
Out[234]: 
array([[ 122.,    1.,  -47.],
       [ 123.,    1.,  -47.],
       [  nan,   nan,   nan],
       [  nan,   nan,   nan],
       [ 126.,    1.,  -44.],
       [  nan,   nan,   nan], (168 NaN rows)
       .....
       [  nan,   nan,   nan],
       [  nan,   nan,   nan],
       [  39.,    1.,  -47.],
       [  40.,    1.,  -45.],
       [  41.,    1.,  -47.]])
  

Подход # 2

Можно было бы предложить альтернативный подход для обработки таких общих случаев, используя np.insert вместо инициализации, например —

 idx = np.flatnonzero(~np.in1d(range_arr,a0))
out = np.insert(arr,idx - np.arange(idx.size),np.nan,axis=0)