Numpy dizisini tuple'a dönüştür


108

Not: Bu, normal diziden diziye dönüşümün tersini istiyor.

İç içe geçmiş bir tuple olarak (sarmalanmış c ++) işlevine bir bağımsız değişken geçirmem gerekiyor. Örneğin aşağıdaki işler

X = MyFunction( ((2,2),(2,-2)) )

Aşağıdaki oysa yok

X = MyFunction( numpy.array(((2,2),(2,-2))) )
X = MyFunction( [[2,2],[2,-2]] )

Ne yazık ki, kullanmak istediğim argüman bana uyuşuk bir dizi olarak geliyor. Bu dizinin bazı N'ler için her zaman 2xN boyutları vardır, bu oldukça büyük olabilir.

Bunu bir demete dönüştürmenin kolay bir yolu var mı? Yeni bir demet oluşturarak sadece döngü yapabileceğimi biliyorum, ancak numpy dizisinin sağladığı güzel bir erişim olup olmadığını tercih ederim.

Bunu umduğum kadar güzel yapmak mümkün değilse, döngü yaparak yapmanın en güzel yolu nedir, ya da her neyse?

Yanıtlar:


157
>>> arr = numpy.array(((2,2),(2,-2)))
>>> tuple(map(tuple, arr))
((2, 2), (2, -2))

29
Yani basit bir 1-d dizisi içintuple(arr)
FindOutIslamNow

26

İşte bunu yapacak bir işlev:

def totuple(a):
    try:
        return tuple(totuple(i) for i in a)
    except TypeError:
        return a

Ve bir örnek:

>>> array = numpy.array(((2,2),(2,-2)))
>>> totuple(array)
((2, 2), (2, -2))

1
Güzel genelleme. Yine de bir python acemi olarak, neredeyse istisnai olmayan durum kadar yaygın olan bir durum için istisnaları kullanmanın iyi bir tarz olup olmadığını merak ediyorum. En azından c ++ 'da, istisnalara göre akış denetimi genellikle hoş karşılanmaz. Test etmek daha iyi olur type(a)==numpy.ndarraymu?
Mike

9
Bu, python'da "ördek yazma" ve EAFT kavramlarından dolayı oldukça yaygındır, daha fazlası burada: docs.python.org/glossary.html#term-duck-typing . Bu yaklaşımın avantajı, herhangi bir iç içe geçmiş diziyi yalnızca bir diziye değil, iç içe geçmiş demetlere dönüştürmesidir. Düzelttiğim tek şey, dış bloğu tarafından işlenmesini istediğim hataları belirlemektir.
Bi Rico

3
C ++ 'da istisnalar, çeşitli nedenlerle koşullara göre yavaştır. Python'da performans açısından yaklaşık olarak aynıdır - bu, kapıda C ++ sezgilerimizi kontrol etmemiz gereken yerlerden biridir.
dbn

8

Memnun değildim, bu yüzden sonunda şunu kullandım:

>>> a=numpy.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])

>>> tuple(a.reshape(1, -1)[0])
(1, 2, 3, 4, 5, 6)

Daha hızlı mı bilmiyorum ama daha etkili görünüyor;)


3
Demet için istediğim şekil bu değildi.
Mike

5

Başka seçenek

tuple([tuple(row) for row in myarray])

NumPy dizilerini C ++ işlevlerine aktarıyorsanız, Cython veya SWIG kullanarak da bakmak isteyebilirsiniz.


Bu tuple'a dönüşmez. Bir listeye mi dönüşür?
Peter

Onu denedin mi? Girdiğimde bir demet oluşturur. Son çağrılan fonksiyonun bir demet döndüren tuple olduğuna dikkat edin. Dış tuple olmadan sadece [...] kısmına sahipseniz, tuplların bir listesini alırsınız.
Greg von Winckel

daha hızlı bir yöntem var mı?
Vicrobot

1
listKöşeli parantezleri tuple(tuple(row) for row in myarray)
çıkararak

1

Uzun kesimleri seviyorsanız, işte başka bir yol tuple (a_m in a_m için tuple (a_m.tolist ()))

from numpy import array
a = array([[1, 2],
           [3, 4]])
tuple(tuple(a_m.tolist()) for a_m in a )

Çıktı ((1, 2), (3, 4))

Sadece (tuple (a_m.tolist ()), a'daki a_m için) bir üretici ifadesi verecektir. @ Norok2'nin Greg von Winckel'in cevabına yaptığı yorumdan esinlenildi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.