Tableau de 0, 1 vers un mot binaire (python) — Les-mathematiques.net The most powerful custom community solution in the world

Tableau de 0, 1 vers un mot binaire (python)

Bonjour
J'ai un tableau (array de numpy) de 0 et de 1, mais je ne trouve aucune manière de le transformer en mot binaire.

Par exemple : 1,0,0], [0,1,0],[0,0,1 vers : b'100010001'.

En gros je veux les rajouter les colonnes les unes après les autres.
Merci.

Réponses

  • Une façon un peu laborieuse.
    e = [[1,0,0], [0,1,0],[0,0,1]]
    b''.join([bytes(str(g),'ascii') for f in e for g in f])
    
  • Regarde du côté des instructions "flatten" et "ravel" pour commencer

    Paul
  • Est-ce ce que tu recherches ?
    import numpy as np
    N = 3
    a = np.eye(N, dtype = np.int)
    b = a.flatten()
    c = b.tobytes()
    print(c)
    
  • Ou peut-être cette variation :
    >>> import numpy as np
    >>> N = 10
    >>> (np.eye(N, dtype='uint8').flatten() + ord('0')).tobytes()
    b'1000000000010000000000100000000001000000000010000000000100000000001000000000010000000000100000000001'
    
  • Merci pour vos réponses, lorsque j'ai fait .tobytes() ça me mettait chaque éléments du tableau sur 2 bytes.

    Par exemple : 0 -> x00, 1 -> x01.
  • C'est la méthode qui m'a donné le résultat qui se rapproche de ce que je cherche, mais cela me met les lignes les une après les autres et non les colonnes.
    Merci bien, je vais essayer d'utiliser cette méthode pour ce que je cherche.

    EDIT:
    Bon en transposant le tableau et en utilisant ta méthode ça marche parfaitement.
    Penses-tu que cela peut passer si je dois faire ça des centaines de fois (dans un algorithme d'intelligence artificielle) ?
  • Plutôt que de transposer, essaie avec <comme ci-dessus>.tobytes('F'). Voir la doc de numpy.ndarray.tobytes(). Pour les performances, je ne peux pas vraiment répondre : je n'ai pas l'habitude de jouer avec de gros tableaux.

    Edit : en fait, pour que la conversion par tobytes() soit la plus rapide possible, le mieux est probablement de créer le tableau d'origine en column-major mode avec
    np.ndarray(..., order='F')
    
    et d'utiliser tobytes() sans aucun paramètre — ou avec 'F', ça ne devrait rien changer dans ce cas.
  • Tableau = np.array([[0, 0, 0, 0, 0, 0, 1],
    ...                  [1, 0, 0, 0, 0, 0, 0],
    ...                  [0, 0, 0, 0, 0, 0, 1],
    ...                  [1, 0, 0, 0, 0, 0, 0],
    ...                  [0, 0, 0, 0, 0, 0, 1],
    ...                  [1, 0, 0, 0, 0, 0, 0],
    ...                  [0, 0, 0, 0, 0, 0, 0],
    ...                  [0, 0, 0, 0, 0, 0, 0]])
    b''.join([bytes(str(g),'ascii') for f in Tableau.T for g in f])
    b'01010100000000000000000000000000000000000000000010101000'
    
    Tableau.tobytes('F')
    b'\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    

    Le problème c'est que tobytes('F') fait quelque chose de bizarre que je ne comprends pas.
    Le premier résultat m'intéresse, mais le problème c'est que j'ai peur que ça ne soit pas efficace.

    (En gros je dois faire une I.A. qui va jouer à un jeu contre l'I.A. d'autres personnes de ma classe et donc mon but c'est de faire le code le moins lourd possible pour pouvoir aller le plus loin dans mon arbre de décision dans les 10 secondes données pour chaque tour)
  • Bon, on dirait que la création d'un np.ndarray ignore order='F' chez moi, mais quel est le problème avec ceci ?
    >>> a = np.array([[0, 0, 0, 0, 0, 0, 1],
    ...               [1, 0, 0, 0, 0, 0, 0],
    ...               [0, 0, 0, 0, 0, 0, 1],
    ...               [1, 0, 0, 0, 0, 0, 0],
    ...               [0, 0, 0, 0, 0, 0, 1],
    ...               [1, 0, 0, 0, 0, 0, 0],
    ...               [0, 0, 0, 0, 0, 0, 0],
    ...               [0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)
    >>> 
    >>> (a + ord('0')).tobytes('F')
    b'01010100000000000000000000000000000000000000000010101000'
    
    C'est ce que tu veux, non ?

    Attention : j'ai mis 'dtype=np.uint8' pour la création tu tableau. C'est a priori « moins pire » que la valeur par défaut pour économiser l'espace mémoire, en revanche ce n'est pas forcément le type d'entier qui donnera les meilleures performances sur une architecture du genre amd64. Si la place occupée en mémoire n'est pas un problème, il est peut-être préférable d'utiliser 'dtype=np.intc', 'dtype=np.uintc' ou quelque chose de ce genre.
  • Oui exactement c'est le résultat que je veux.

    Je ne suis pas trop connaisseur sur le type d'architecture (je serais curieux d'apprendre ça), mais la place mémoire me semble très importante ici.

    Je suis en train de faire un algorithme utilisant l'élagage alpha-beta, donc à chaque tour j'aurais jusqu'à $20^d$ tableaux de la sorte générés où $d$ sera la limite que je vais imposer à mon algorithme pour qu'il n'implose pas.
  • Si la place mémoire est très importante, lis bien le tutoriel NumPy autour de ce bout de code :
    >>> a = np.arange(int(1e8))
    >>> b = a[:100].copy()
    >>> del a  # the memory of ``a`` can be released.
    
    Si tu veux que le garbage collector de Python (« ramasse-miettes ») fasse bien son boulot, ne laisse pas traîner des références vers les gros objects dans d'autres objects qui « restent en vie » après que les premiers ne sont plus utiles, etc.
  • Personnellement je préfère ce type de "deep copy". Je suis aussi partisan d'effacer explicitement une variable quand elle devient inutile.

    Dans le code ci-dessous, ça commence à coincer pour N > 3 milliard avec mes 6 Go de mémoire (sous Linux)
    N = int(1.e9)
    n1 = 100
    n2 = 1569
    a = np.random.randint(2, size=N, dtype=np.uint8)
    b = np.copy(a[n1:n2])
    del a
    
  • regunhd a écrit:
    Le problème c'est que tobytes('F') fait quelque chose de bizarre que je ne comprends pas. Le premier résultat m'intéresse, mais le problème c'est que j'ai peur que ça ne soit pas efficace.

    Le type bytes est un type non mutable similaire à une chaîne de caractères mais sans encodage. C’est un tableau non mutable d’octets.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
Connectez-vous ou Inscrivez-vous pour répondre.
Success message!