Получение массива сокращенных списков? - PullRequest
0 голосов
/ 18 октября 2019

Рассмотрим этот код:

#!/usr/bin/env python3

import numpy as np

aa = [
  [3, 8, [37, 7, 5, 0, 5, 0, 8, 0]],
  [3, 8, [36, 7, 5, 0, 4, 0, 8, 0]],
  [3, 8, [37, 7, 5, 0, 4, 0, 8, 0]],
  [3, 8, [37, 7, 5, 0, 5, 0, 9, 0]],
  [3, 8, [36, 7, 6, 0, 6, 0, 12, 0]],
  [3, 8, [36, 7, 5, 0, 5, 0, 9, 0]],
  [3, 8, [36, 7, 5, 0, 5, 0, 8, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 10, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 10, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 12, 0]]
]

nch = np.asarray(aa, dtype=object)

print("nch shape {}".format(nch.shape))
print(nch)
nchB = nch[:,2]
print("nchB shape {}".format(nchB.shape))
print(nchB)

print("Test 1")
print( np.frompyfunc(list, 0, 1)(np.empty((3,2), dtype=object)) )
print("Test 2")
print( np.frompyfunc(list, 0, 1)(nchB) )
print("Test 3")
print( np.frompyfunc(list, 1, 1)( nchB ) )

Он выводит:

nch shape (10, 3)
[[3 8 list([37, 7, 5, 0, 5, 0, 8, 0])]
 [3 8 list([36, 7, 5, 0, 4, 0, 8, 0])]
 [3 8 list([37, 7, 5, 0, 4, 0, 8, 0])]
 [3 8 list([37, 7, 5, 0, 5, 0, 9, 0])]
 [3 8 list([36, 7, 6, 0, 6, 0, 12, 0])]
 [3 8 list([36, 7, 5, 0, 5, 0, 9, 0])]
 [3 8 list([36, 7, 5, 0, 5, 0, 8, 0])]
 [3 8 list([37, 7, 6, 0, 6, 0, 10, 0])]
 [3 8 list([37, 7, 6, 0, 6, 0, 10, 0])]
 [3 8 list([37, 7, 6, 0, 6, 0, 12, 0])]]
nchB shape (10,)
[list([37, 7, 5, 0, 5, 0, 8, 0]) list([36, 7, 5, 0, 4, 0, 8, 0])
 list([37, 7, 5, 0, 4, 0, 8, 0]) list([37, 7, 5, 0, 5, 0, 9, 0])
 list([36, 7, 6, 0, 6, 0, 12, 0]) list([36, 7, 5, 0, 5, 0, 9, 0])
 list([36, 7, 5, 0, 5, 0, 8, 0]) list([37, 7, 6, 0, 6, 0, 10, 0])
 list([37, 7, 6, 0, 6, 0, 10, 0]) list([37, 7, 6, 0, 6, 0, 12, 0])]
Test 1
[[list([]) list([])]
 [list([]) list([])]
 [list([]) list([])]]
Test 2
[list([]) list([]) list([]) list([]) list([]) list([]) list([]) list([])
 list([]) list([])]
Test 3
[list([]) list([]) list([]) list([]) list([]) list([]) list([]) list([])
 list([]) list([])]

По сути, я использую что-то вроде nchB для подачи блокпоста matplotlib, который отлично работает.

nchB здесь считается одноразмерным массивом длины 10 с элементами, являющимися списками;здесь так и происходит, каждый из этих списков состоит из 8 элементов.

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

[list([37, 7]) list([36, 7])
 list([37, 7]) list([37, 7])
 list([36, 7]) list([36, 7])
 list([36, 7]) list([37, 7])
 list([37, 7]) list([37, 7])]

или:

[list([37]) list([36])
 list([37]) list([37])
 list([36]) list([36])
 list([36]) list([37])
 list([37]) list([37])]

... каким-то образом из nchB, предпочтительно с использованием однострочника - тогда я мог бы использоватьэтот «сокращенный» массив списков для подачи данных о полевых боксах maxplotlib для инициализации (так что я могу начать настройку графика, и мне не придется долго ждать, пока мои фактические данные будут отображены).

Как можноЯ делаю это? Очевидно, что тривиальные попытки, которые я предпринял в «Тесте 2» и «Тесте 3» выше с np.frompyfunc, которые я нашел из:

... не совсем работает, так как все, что я получаю, это пустые списки.

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Вы почти на месте:

slice_two = np.frompyfunc(lambda x: x[:2], 1, 1)
slice_two(nchB)

# [list([37, 7]) list([36, 7]) 
#  list([37, 7]) list([37, 7]) 
#  list([36, 7]) list([36, 7]) 
#  list([36, 7]) list([37, 7]) 
#  list([37, 7]) list([37, 7])]

slice_one = np.frompyfunc(lambda x: x[:1], 1, 1)
slice_one(nchB)

# [list([37]) list([36]) 
#  list([37]) list([37]) 
#  list([36]) list([36])
#  list([36]) list([37]) 
#  list([37]) list([37])]

И это также не влияет на исходные данные:

print(nchB)
# [list([37, 7, 5, 0, 5, 0, 8, 0])  list([36, 7, 5, 0, 4, 0, 8, 0])
#  list([37, 7, 5, 0, 4, 0, 8, 0])  list([37, 7, 5, 0, 5, 0, 9, 0])
#  list([36, 7, 6, 0, 6, 0, 12, 0]) list([36, 7, 5, 0, 5, 0, 9, 0])
#  list([36, 7, 5, 0, 5, 0, 8, 0])  list([37, 7, 6, 0, 6, 0, 10, 0])
#  list([37, 7, 6, 0, 6, 0, 10, 0]) list([37, 7, 6, 0, 6, 0, 12, 0])]
0 голосов
/ 18 октября 2019

Хорошо, я думаю, что получил где-то - этот код сейчас:

#!/usr/bin/env python3

import numpy as np

aa = [
  [3, 8, [37, 7, 5, 0, 5, 0, 8, 0]],
  [3, 8, [36, 7, 5, 0, 4, 0, 8, 0]],
  [3, 8, [37, 7, 5, 0, 4, 0, 8, 0]],
  [3, 8, [37, 7, 5, 0, 5, 0, 9, 0]],
  [3, 8, [36, 7, 6, 0, 6, 0, 12, 0]],
  [3, 8, [36, 7, 5, 0, 5, 0, 9, 0]],
  [3, 8, [36, 7, 5, 0, 5, 0, 8, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 10, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 10, 0]],
  [3, 8, [37, 7, 6, 0, 6, 0, 12, 0]]
]

nch = np.asarray(aa, dtype=object)

print("nch shape {}".format(nch.shape))
print(nch)
nchB = nch[:,2]
print("nchB shape {}".format(nchB.shape))
print(nchB)
#print([i[0] for i in nchB])
#print([ [i[0], i[1]] for i in nchB])
#print(np.asarray([ [i[0], i[1]] for i in nchB], dtype=object))
#print(   np.frompyfunc(list, 1, 1)( np.asarray([ [i[0], i[1]] for i in nchB], dtype=object) )   ) # TypeError: 'int' object is not iterable
#~ print(   np.frompyfunc(list, 1, 1)( [ [i[0], i[1]] for i in nchB] )   )
print(   np.frompyfunc(list, 1, 1)( i for i in nchB )   )

print("Test 1")
print( np.frompyfunc(list, 0, 1)(np.empty((3,2), dtype=object)) )

# print("Test 2")
# print( np.frompyfunc(list, 0, 1)(nchB) )
# print("nchB", nchB) # deleted!? nchB [list([]) list([]) list([]) list([]) list([]) list([]) list([]) list([]) list([]) list([])]

print("Test 3")
print( np.frompyfunc(list, 1, 1)( nchB ) )
#print("nchB", nchB) # OK, but does not create empty lists

print("Test 4")
nchBB = np.copy(nchB) # copy, as nchB will get deleted/changed otherwise
blist = np.frompyfunc(list, 0, 1)( nchBB ) # forces empty list, both blist and nchBB
gen = (item.extend( (nchB[ind][0], nchB[ind][1]) ) for ind, item in enumerate(blist))
for _ in gen: pass # https://stackoverflow.com/q/11539194
print("blist", blist) # blist [list([37, 7]) list([36, 7]) ...
print("nchBB", nchBB) # nchBB [list([37, 7]) list([36, 7]) ...

print("shapes:", blist.shape, nchB.shape)

... будет производить:

...
Test 1
[[list([]) list([])]
 [list([]) list([])]
 [list([]) list([])]]
Test 3
[list([37, 7, 5, 0, 5, 0, 8, 0]) list([36, 7, 5, 0, 4, 0, 8, 0])
 list([37, 7, 5, 0, 4, 0, 8, 0]) list([37, 7, 5, 0, 5, 0, 9, 0])
 list([36, 7, 6, 0, 6, 0, 12, 0]) list([36, 7, 5, 0, 5, 0, 9, 0])
 list([36, 7, 5, 0, 5, 0, 8, 0]) list([37, 7, 6, 0, 6, 0, 10, 0])
 list([37, 7, 6, 0, 6, 0, 10, 0]) list([37, 7, 6, 0, 6, 0, 12, 0])]
Test 4
blist [list([37, 7]) list([36, 7]) list([37, 7]) list([37, 7]) list([36, 7])
 list([36, 7]) list([36, 7]) list([37, 7]) list([37, 7]) list([37, 7])]
nchBB [list([37, 7]) list([36, 7]) list([37, 7]) list([37, 7]) list([36, 7])
 list([36, 7]) list([36, 7]) list([37, 7]) list([37, 7]) list([37, 7])]
shapes: (10,) (10,)

Итак, трюк был:

  • Скопируйте np.array списков источника - как использование np.array в качестве источника для np.frompyfunc изменит его на месте!
  • Заставьте np.frompyfunc вернуть пустые списки, дляполные списки в источнике np.array
  • Создайте генераторное выражение, которое циклически перебирает пустые списки np.frompyfunc, и расширьте эти пустые списки первыми двумя элементами исходного np.array (который теперь полностьюдоступный, так как он был скопирован и, таким образом, остался неизменным np.frompyfunc)

Я надеялся, что это будет проще и / или выполнимо с однострочником, но вы идете .. По крайней мере, усеченный nchBB и исходный nchB теперь все еще имеют одинаковую форму с точки зрения numpy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...