2016-08-12 2 views
0

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

markerList # a long list of every marker in every frame markerList[0] # every marker in the first frame markerList[0][0] # the first marker of the first frame markerList[0][0][0] # the x value of the first marker of the first frame

Вызов markerList [0] выглядит следующим образом:

array([[ 922.04443359, 903.  ], 
    [ 987.83850098, 891.38830566], 
    [ 843.27374268, 891.70471191], 
    [ 936.38446045, 873.34661865], 
    [ 965.52880859, 840.44445801], 
    [ 822.19567871, 834.06298828], 
    [ 903.48956299, 830.62268066], 
    [ 938.70031738, 825.71557617], 
    [ 853.09545898, 824.47247314], 
    [ 817.84277344, 816.05029297], 
    [ 1057.91186523, 815.52935791], 
    [ 833.23632812, 787.48504639], 
    [ 924.24224854, 755.53997803], 
    [ 836.07800293, 720.02764893], 
    [ 937.83880615, 714.11199951], 
    [ 813.3493042 , 720.30566406], 
    [ 797.09521484, 705.72729492], 
    [ 964.31713867, 703.246521 ], 
    [ 934.9864502 , 697.27099609], 
    [ 815.1550293 , 688.91473389], 
    [ 954.94085693, 685.88171387], 
    [ 797.70239258, 672.35119629], 
    [ 877.05749512, 659.94250488], 
    [ 962.24786377, 659.26495361], 
    [ 843.66131592, 618.83868408], 
    [ 901.50476074, 585.42541504], 
    [ 863.41851807, 584.4977417 ]], dtype=float32) 

Проблема заключается в том, что каждый кадр содержит разное количество маркеров. Я хочу создать пустой массив той же длины, что и маркерList (т. Е. Такое же количество кадров), в котором каждый элемент имеет тот же размер, что и самый большой кадр в методе labelList. Некоторые важные оговорки: во-первых, я хочу сохранить результаты в файл .mat, где конечный массив (который я буду называть finalStack) является ячейкой ячеек. Во-вторых, мне нужно иметь возможность ссылаться на какую-либо определенную часть finalStack. Поэтому, если я хочу переместить точку в finalStack [0] [22], мне нужно иметь возможность сделать это без конфликтов. Это в основном означает, что я не могу использовать методы добавления в любом месте, но он также обнаружил мою первую проблему - найти способ создания finalStack, который не вызывает дублирования каждого нового присвоения во всем родительском списке. Я попытался сделать это несколькими разными способами, и никто не работает правильно.

Попытки решения:

После другой СЦ вопрос, я попытался создать finalStack итеративно, но безрезультатно. Я создал следующую функцию:

def createFinalStack(numMarkers, numPoints, frames): 
    step = [[0]*numPoints for x in xrange(numMarkers)] 
    finalStack = [step]*frames 
    return finalStack 

Однако, это вызывает все задания, которые будут скопированы в родительском списке, например, что назначение finalStack[0][12] приводит к finalStack[2][12] == finalStack[20][12] == finalStack[0][12]. В этом примере numMarkers = 40, numPoints = 2 (только xy) и frames = 200. (Таким образом, конечный массив должен быть 200 x 40 x 2.)

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

Другим, по-видимому, простым решением было бы скопировать маркерList с использованием copy.deepcopy(markerList) и проложить любые кадры с менее чем 40 маркерами, чтобы получить их в numMarkers = 40 и нулевое из чего угодно. Но я не могу придумать хороший способ перебирать все фреймы, добавлять точки в правильном формате и затем опустошать все остальное.

Если этого недостаточно для работы, я могу попытаться обеспечить больший контекст и некоторые другие не-хорошие методы, которые вообще не работали. Я застрял на этом достаточно долго, что я убежден, что решение ужасно просто, и я просто пропущу очевидное. Надеюсь, ты сможешь доказать мне правду!

Спасибо!

+0

Это копирование по родительским спискам из-за '[0] * numPoints'. Попробуйте заменить это на '[0 для _ в диапазоне (len (numPoints))]' или 'np.zeros (numPoints)' – Anonymous

+0

Это создает проблемы с сохранением в качестве мата, поскольку он не может передавать входной массив из формы (40, 2) для формирования (40). Представляется специфичным для этого метода; Раньше у меня никогда не было проблемы. Для справки, метод сохранения: 'matdict = dict (markers = (markerList), sorted = (finalStack)) scipy.io.savemat ('pathname.mat', matdict)'. – godfreap

ответ

1

Это иллюстрирует то, что происходит:

In [1334]: step=[[0]*3 for x in range(3)] 
In [1335]: step 
Out[1335]: [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 
In [1336]: stack=[step]*4 
In [1337]: stack 
Out[1337]: 
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 
In [1338]: stack[0] 
Out[1338]: [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 
In [1339]: stack[0][2]=3 
In [1340]: stack 
Out[1340]: 
[[[0, 0, 0], [0, 0, 0], 3], 
[[0, 0, 0], [0, 0, 0], 3], 
[[0, 0, 0], [0, 0, 0], 3], 
[[0, 0, 0], [0, 0, 0], 3]] 
In [1341]: step 
Out[1341]: [[0, 0, 0], [0, 0, 0], 3] 

При использовании alist*n создать новый список, новый список содержит несколько указателей на тот же базовый объект. Как правило, использование *n для тиражирования списка опасно, если позже вы планируете изменить значения.

Если вместо этого я сделать массив нужных размеров у меня нет этой проблемы:

In [1342]: np.zeros((4,3,3),int) 
Out[1342]: 
array([[[0, 0, 0], 
     [0, 0, 0], 
     [0, 0, 0]], 

     ... 
     [0, 0, 0]]]) 

или в виде списка:

In [1343]: np.zeros((4,3,3),int).tolist() 
Out[1343]: 
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 

Если я присвоить значение в этом списке, Я только изменить один пункт:

In [1344]: stack=np.zeros((4,3,3),int).tolist() 
In [1345]: stack[0][2]=3 
In [1346]: stack 
Out[1346]: 
[[[0, 0, 0], [0, 0, 0], 3], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]] 

Я действительно должен был использовать stack[0][2][1]=3, но вы получите I ДЭА. Если я сделать то же самое назначение в виде массива я в конечном итоге меняется целый ряд

In [1347]: stack=np.zeros((4,3,3),int) 
In [1348]: stack[0][2]=3 
In [1349]: stack 
Out[1349]: 
array([[[0, 0, 0], 
     [0, 0, 0], 
     [3, 3, 3]], 

     [[0, 0, 0], 
     ... 
     [0, 0, 0]]]) 

я должен использовать такое выражение stack[0,2,:]=4.

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

+0

Это, похоже, сработало. Я отправлю ответ, если что-то не сработает, но похоже, что я делаю то, что хочу. Благодаря!! – godfreap